pipeline: add new functions for action handlers
[dpdk.git] / examples / ip_pipeline / pipeline / pipeline_actions_common.h
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 #ifndef __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
34 #define __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
35
36 #include <stdint.h>
37
38 #include <rte_common.h>
39 #include <rte_cycles.h>
40 #include <rte_mbuf.h>
41 #include <rte_pipeline.h>
42
43 #define PIPELINE_PORT_IN_AH(f_ah, f_pkt_work, f_pkt4_work)              \
44 static int                                                              \
45 f_ah(                                                                   \
46         __rte_unused struct rte_pipeline *p,                            \
47         struct rte_mbuf **pkts,                                         \
48         uint32_t n_pkts,                                                \
49         void *arg)                                                      \
50 {                                                                       \
51         uint32_t i;                                                     \
52                                                                         \
53         for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)                   \
54                 f_pkt4_work(&pkts[i], arg);                             \
55                                                                         \
56         for ( ; i < n_pkts; i++)                                        \
57                 f_pkt_work(pkts[i], arg);                               \
58                                                                         \
59         return 0;                                                       \
60 }
61
62 #define PIPELINE_TABLE_AH_HIT(f_ah, f_pkt_work, f_pkt4_work)            \
63 static int                                                              \
64 f_ah(                                                                   \
65         __rte_unused struct rte_pipeline *p,                            \
66         struct rte_mbuf **pkts,                                         \
67         uint64_t pkts_in_mask,                                          \
68         struct rte_pipeline_table_entry **entries,                      \
69         void *arg)                                                      \
70 {                                                                       \
71         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
72                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
73                 uint32_t i;                                             \
74                                                                         \
75                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)           \
76                         f_pkt4_work(&pkts[i], &entries[i], arg);        \
77                                                                         \
78                 for ( ; i < n_pkts; i++)                                \
79                         f_pkt_work(pkts[i], entries[i], arg);           \
80         } else                                                          \
81                 for ( ; pkts_in_mask; ) {                               \
82                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
83                         uint64_t pkt_mask = 1LLU << pos;                \
84                                                                         \
85                         pkts_in_mask &= ~pkt_mask;                      \
86                         f_pkt_work(pkts[pos], entries[pos], arg);       \
87                 }                                                       \
88                                                                         \
89         return 0;                                                       \
90 }
91
92 #define PIPELINE_TABLE_AH_MISS(f_ah, f_pkt_work, f_pkt4_work)           \
93 static int                                                              \
94 f_ah(                                                                   \
95         __rte_unused struct rte_pipeline *p,                            \
96         struct rte_mbuf **pkts,                                         \
97         uint64_t pkts_in_mask,                                          \
98         struct rte_pipeline_table_entry *entry,                         \
99         void *arg)                                                      \
100 {                                                                       \
101         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
102                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
103                 uint32_t i;                                             \
104                                                                         \
105                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4)           \
106                         f_pkt4_work(&pkts[i], entry, arg);              \
107                                                                         \
108                 for ( ; i < n_pkts; i++)                                \
109                         f_pkt_work(pkts[i], entry, arg);                \
110         } else                                                          \
111                 for ( ; pkts_in_mask; ) {                               \
112                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
113                         uint64_t pkt_mask = 1LLU << pos;                \
114                                                                         \
115                         pkts_in_mask &= ~pkt_mask;                      \
116                         f_pkt_work(pkts[pos], entry, arg);              \
117                 }                                                       \
118                                                                         \
119         return 0;                                                       \
120 }
121
122 #define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work)  \
123 static int                                                              \
124 f_ah(                                                                   \
125         struct rte_pipeline *p,                                         \
126         struct rte_mbuf **pkts,                                         \
127         uint64_t pkts_mask,                                             \
128         struct rte_pipeline_table_entry **entries,                      \
129         void *arg)                                                      \
130 {                                                                       \
131         uint64_t pkts_in_mask = pkts_mask;                              \
132         uint64_t pkts_out_mask = pkts_mask;                             \
133         uint64_t time = rte_rdtsc();                                    \
134                                                                         \
135         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
136                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
137                 uint32_t i;                                             \
138                                                                         \
139                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
140                         uint64_t mask = f_pkt4_work(&pkts[i],           \
141                                 &entries[i], arg, time);                \
142                         pkts_out_mask ^= mask << i;                     \
143                 }                                                       \
144                                                                         \
145                 for ( ; i < n_pkts; i++) {                              \
146                         uint64_t mask = f_pkt_work(pkts[i],             \
147                                 entries[i], arg, time);                 \
148                         pkts_out_mask ^= mask << i;                     \
149                 }                                                       \
150         } else                                                          \
151                 for ( ; pkts_in_mask; ) {                               \
152                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
153                         uint64_t pkt_mask = 1LLU << pos;                \
154                         uint64_t mask = f_pkt_work(pkts[pos],           \
155                                 entries[pos], arg, time);               \
156                                                                         \
157                         pkts_in_mask &= ~pkt_mask;                      \
158                         pkts_out_mask ^= mask << pos;                   \
159                 }                                                       \
160                                                                         \
161         rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);      \
162                                                                         \
163         return 0;                                                       \
164 }
165
166 #define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
167 static int                                                              \
168 f_ah(                                                                   \
169         struct rte_pipeline *p,                                         \
170         struct rte_mbuf **pkts,                                         \
171         uint64_t pkts_mask,                                             \
172         struct rte_pipeline_table_entry *entry,                         \
173         void *arg)                                                      \
174 {                                                                       \
175         uint64_t pkts_in_mask = pkts_mask;                              \
176         uint64_t pkts_out_mask = pkts_mask;                             \
177         uint64_t time = rte_rdtsc();                                    \
178                                                                         \
179         if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) {                 \
180                 uint64_t n_pkts = __builtin_popcountll(pkts_in_mask);   \
181                 uint32_t i;                                             \
182                                                                         \
183                 for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {         \
184                         uint64_t mask = f_pkt4_work(&pkts[i],           \
185                                 entry, arg, time);                      \
186                         pkts_out_mask ^= mask << i;                     \
187                 }                                                       \
188                                                                         \
189                 for ( ; i < n_pkts; i++) {                              \
190                         uint64_t mask = f_pkt_work(pkts[i], entry, arg, time);\
191                         pkts_out_mask ^= mask << i;                     \
192                 }                                                       \
193         } else                                                          \
194                 for ( ; pkts_in_mask; ) {                               \
195                         uint32_t pos = __builtin_ctzll(pkts_in_mask);   \
196                         uint64_t pkt_mask = 1LLU << pos;                \
197                         uint64_t mask = f_pkt_work(pkts[pos],           \
198                                 entry, arg, time);              \
199                                                                         \
200                         pkts_in_mask &= ~pkt_mask;                      \
201                         pkts_out_mask ^= mask << pos;                   \
202                 }                                                       \
203                                                                         \
204         rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask);      \
205                                                                         \
206         return 0;                                                       \
207 }
208
209 #endif