Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2020 Mellanox Technologies, Ltd
3 : : *
4 : : * This file contain the implementations of the items
5 : : * related methods. Each Item have a method to prepare
6 : : * the item and add it into items array in given index.
7 : : */
8 : :
9 : : #include <stdint.h>
10 : : #include <rte_flow.h>
11 : :
12 : : #include "items_gen.h"
13 : : #include "config.h"
14 : :
15 : : /* Storage for additional parameters for items */
16 : : struct additional_para {
17 : : rte_be32_t src_ip;
18 : : uint8_t core_idx;
19 : : };
20 : :
21 : : static void
22 : 0 : add_ether(struct rte_flow_item *items,
23 : : uint8_t items_counter,
24 : : __rte_unused struct additional_para para)
25 : : {
26 : : static struct rte_flow_item_eth eth_spec;
27 : : static struct rte_flow_item_eth eth_mask;
28 : :
29 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_ETH;
30 : 0 : items[items_counter].spec = ð_spec;
31 : 0 : items[items_counter].mask = ð_mask;
32 : 0 : }
33 : :
34 : : static void
35 : 0 : add_vlan(struct rte_flow_item *items,
36 : : uint8_t items_counter,
37 : : __rte_unused struct additional_para para)
38 : : {
39 : : static struct rte_flow_item_vlan vlan_spec = {
40 : : .hdr.vlan_tci = RTE_BE16(VLAN_VALUE),
41 : : };
42 : : static struct rte_flow_item_vlan vlan_mask = {
43 : : .hdr.vlan_tci = RTE_BE16(0xffff),
44 : : };
45 : :
46 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_VLAN;
47 : 0 : items[items_counter].spec = &vlan_spec;
48 : 0 : items[items_counter].mask = &vlan_mask;
49 : 0 : }
50 : :
51 : : static void
52 : 0 : add_ipv4(struct rte_flow_item *items,
53 : : uint8_t items_counter, struct additional_para para)
54 : : {
55 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_ipv4 ipv4_specs[RTE_MAX_LCORE];
56 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_ipv4 ipv4_masks[RTE_MAX_LCORE];
57 : 0 : uint8_t ti = para.core_idx;
58 : :
59 : 0 : ipv4_specs[ti].hdr.src_addr = RTE_BE32(para.src_ip);
60 : 0 : ipv4_masks[ti].hdr.src_addr = RTE_BE32(0xffffffff);
61 : :
62 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV4;
63 : 0 : items[items_counter].spec = &ipv4_specs[ti];
64 : 0 : items[items_counter].mask = &ipv4_masks[ti];
65 : 0 : }
66 : :
67 : :
68 : : static void
69 : 0 : add_ipv6(struct rte_flow_item *items,
70 : : uint8_t items_counter, struct additional_para para)
71 : : {
72 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_ipv6 ipv6_specs[RTE_MAX_LCORE];
73 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_ipv6 ipv6_masks[RTE_MAX_LCORE];
74 : 0 : uint8_t ti = para.core_idx;
75 : : uint8_t i;
76 : :
77 : : /** Set ipv6 src **/
78 : 0 : for (i = 0; i < 16; i++) {
79 : : /* Currently src_ip is limited to 32 bit */
80 : 0 : if (i < 4)
81 : 0 : ipv6_specs[ti].hdr.src_addr.a[15 - i] = para.src_ip >> (i * 8);
82 : 0 : ipv6_masks[ti].hdr.src_addr.a[15 - i] = 0xff;
83 : : }
84 : :
85 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_IPV6;
86 : 0 : items[items_counter].spec = &ipv6_specs[ti];
87 : 0 : items[items_counter].mask = &ipv6_masks[ti];
88 : 0 : }
89 : :
90 : : static void
91 : 0 : add_tcp(struct rte_flow_item *items,
92 : : uint8_t items_counter,
93 : : __rte_unused struct additional_para para)
94 : : {
95 : : static struct rte_flow_item_tcp tcp_spec;
96 : : static struct rte_flow_item_tcp tcp_mask;
97 : :
98 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_TCP;
99 : 0 : items[items_counter].spec = &tcp_spec;
100 : 0 : items[items_counter].mask = &tcp_mask;
101 : 0 : }
102 : :
103 : : static void
104 : 0 : add_udp(struct rte_flow_item *items,
105 : : uint8_t items_counter,
106 : : __rte_unused struct additional_para para)
107 : : {
108 : : static struct rte_flow_item_udp udp_spec;
109 : : static struct rte_flow_item_udp udp_mask;
110 : :
111 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_UDP;
112 : 0 : items[items_counter].spec = &udp_spec;
113 : 0 : items[items_counter].mask = &udp_mask;
114 : 0 : }
115 : :
116 : : static void
117 : 0 : add_vxlan(struct rte_flow_item *items,
118 : : uint8_t items_counter,
119 : : struct additional_para para)
120 : : {
121 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_vxlan vxlan_specs[RTE_MAX_LCORE];
122 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_vxlan vxlan_masks[RTE_MAX_LCORE];
123 : 0 : uint8_t ti = para.core_idx;
124 : : uint32_t vni_value;
125 : : uint8_t i;
126 : :
127 : : vni_value = VNI_VALUE;
128 : :
129 : : /* Set standard vxlan vni */
130 : 0 : for (i = 0; i < 3; i++) {
131 : 0 : vxlan_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8);
132 : 0 : vxlan_masks[ti].hdr.vni[2 - i] = 0xff;
133 : : }
134 : :
135 : : /* Standard vxlan flags */
136 : 0 : vxlan_specs[ti].hdr.flags = 0x8;
137 : :
138 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN;
139 : 0 : items[items_counter].spec = &vxlan_specs[ti];
140 : 0 : items[items_counter].mask = &vxlan_masks[ti];
141 : 0 : }
142 : :
143 : : static void
144 : 0 : add_vxlan_gpe(struct rte_flow_item *items,
145 : : uint8_t items_counter,
146 : : __rte_unused struct additional_para para)
147 : : {
148 : : static alignas(RTE_CACHE_LINE_SIZE)
149 : : struct rte_flow_item_vxlan_gpe vxlan_gpe_specs[RTE_MAX_LCORE];
150 : : static alignas(RTE_CACHE_LINE_SIZE)
151 : : struct rte_flow_item_vxlan_gpe vxlan_gpe_masks[RTE_MAX_LCORE];
152 : 0 : uint8_t ti = para.core_idx;
153 : : uint32_t vni_value;
154 : : uint8_t i;
155 : :
156 : : vni_value = VNI_VALUE;
157 : :
158 : : /* Set vxlan-gpe vni */
159 : 0 : for (i = 0; i < 3; i++) {
160 : 0 : vxlan_gpe_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8);
161 : 0 : vxlan_gpe_masks[ti].hdr.vni[2 - i] = 0xff;
162 : : }
163 : :
164 : : /* vxlan-gpe flags */
165 : 0 : vxlan_gpe_specs[ti].hdr.flags = 0x0c;
166 : :
167 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE;
168 : 0 : items[items_counter].spec = &vxlan_gpe_specs[ti];
169 : 0 : items[items_counter].mask = &vxlan_gpe_masks[ti];
170 : 0 : }
171 : :
172 : : static void
173 : 0 : add_gre(struct rte_flow_item *items,
174 : : uint8_t items_counter,
175 : : __rte_unused struct additional_para para)
176 : : {
177 : : static struct rte_flow_item_gre gre_spec = {
178 : : .protocol = RTE_BE16(RTE_ETHER_TYPE_TEB),
179 : : };
180 : : static struct rte_flow_item_gre gre_mask = {
181 : : .protocol = RTE_BE16(0xffff),
182 : : };
183 : :
184 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_GRE;
185 : 0 : items[items_counter].spec = &gre_spec;
186 : 0 : items[items_counter].mask = &gre_mask;
187 : 0 : }
188 : :
189 : : static void
190 : 0 : add_geneve(struct rte_flow_item *items,
191 : : uint8_t items_counter,
192 : : __rte_unused struct additional_para para)
193 : : {
194 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_geneve geneve_specs[RTE_MAX_LCORE];
195 : : static alignas(RTE_CACHE_LINE_SIZE) struct rte_flow_item_geneve geneve_masks[RTE_MAX_LCORE];
196 : 0 : uint8_t ti = para.core_idx;
197 : : uint32_t vni_value;
198 : : uint8_t i;
199 : :
200 : : vni_value = VNI_VALUE;
201 : :
202 : 0 : for (i = 0; i < 3; i++) {
203 : 0 : geneve_specs[ti].vni[2 - i] = vni_value >> (i * 8);
204 : 0 : geneve_masks[ti].vni[2 - i] = 0xff;
205 : : }
206 : :
207 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_GENEVE;
208 : 0 : items[items_counter].spec = &geneve_specs[ti];
209 : 0 : items[items_counter].mask = &geneve_masks[ti];
210 : 0 : }
211 : :
212 : : static void
213 : 0 : add_gtp(struct rte_flow_item *items,
214 : : uint8_t items_counter,
215 : : __rte_unused struct additional_para para)
216 : : {
217 : : static struct rte_flow_item_gtp gtp_spec = {
218 : : .hdr.teid = RTE_BE32(TEID_VALUE),
219 : : };
220 : : static struct rte_flow_item_gtp gtp_mask = {
221 : : .hdr.teid = RTE_BE32(0xffffffff),
222 : : };
223 : :
224 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_GTP;
225 : 0 : items[items_counter].spec = >p_spec;
226 : 0 : items[items_counter].mask = >p_mask;
227 : 0 : }
228 : :
229 : : static void
230 : 0 : add_meta_data(struct rte_flow_item *items,
231 : : uint8_t items_counter,
232 : : __rte_unused struct additional_para para)
233 : : {
234 : : static struct rte_flow_item_meta meta_spec = {
235 : : .data = RTE_BE32(META_DATA),
236 : : };
237 : : static struct rte_flow_item_meta meta_mask = {
238 : : .data = RTE_BE32(0xffffffff),
239 : : };
240 : :
241 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_META;
242 : 0 : items[items_counter].spec = &meta_spec;
243 : 0 : items[items_counter].mask = &meta_mask;
244 : 0 : }
245 : :
246 : :
247 : : static void
248 : 0 : add_meta_tag(struct rte_flow_item *items,
249 : : uint8_t items_counter,
250 : : __rte_unused struct additional_para para)
251 : : {
252 : : static struct rte_flow_item_tag tag_spec = {
253 : : .data = RTE_BE32(META_DATA),
254 : : .index = TAG_INDEX,
255 : : };
256 : : static struct rte_flow_item_tag tag_mask = {
257 : : .data = RTE_BE32(0xffffffff),
258 : : .index = 0xff,
259 : : };
260 : :
261 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_TAG;
262 : 0 : items[items_counter].spec = &tag_spec;
263 : 0 : items[items_counter].mask = &tag_mask;
264 : 0 : }
265 : :
266 : : static void
267 : 0 : add_icmpv4(struct rte_flow_item *items,
268 : : uint8_t items_counter,
269 : : __rte_unused struct additional_para para)
270 : : {
271 : : static struct rte_flow_item_icmp icmpv4_spec;
272 : : static struct rte_flow_item_icmp icmpv4_mask;
273 : :
274 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_ICMP;
275 : 0 : items[items_counter].spec = &icmpv4_spec;
276 : 0 : items[items_counter].mask = &icmpv4_mask;
277 : 0 : }
278 : :
279 : : static void
280 : 0 : add_icmpv6(struct rte_flow_item *items,
281 : : uint8_t items_counter,
282 : : __rte_unused struct additional_para para)
283 : : {
284 : : static struct rte_flow_item_icmp6 icmpv6_spec;
285 : : static struct rte_flow_item_icmp6 icmpv6_mask;
286 : :
287 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_ICMP6;
288 : 0 : items[items_counter].spec = &icmpv6_spec;
289 : 0 : items[items_counter].mask = &icmpv6_mask;
290 : 0 : }
291 : :
292 : : void
293 : 0 : fill_items(struct rte_flow_item *items,
294 : : uint64_t *flow_items, uint32_t outer_ip_src,
295 : : uint8_t core_idx)
296 : : {
297 : : uint8_t items_counter = 0;
298 : : uint8_t i, j;
299 : 0 : struct additional_para additional_para_data = {
300 : : .src_ip = outer_ip_src,
301 : : .core_idx = core_idx,
302 : : };
303 : :
304 : : /* Support outer items up to tunnel layer only. */
305 : : static const struct items_dict {
306 : : uint64_t mask;
307 : : void (*funct)(
308 : : struct rte_flow_item *items,
309 : : uint8_t items_counter,
310 : : struct additional_para para
311 : : );
312 : : } items_list[] = {
313 : : {
314 : : .mask = RTE_FLOW_ITEM_TYPE_META,
315 : : .funct = add_meta_data,
316 : : },
317 : : {
318 : : .mask = RTE_FLOW_ITEM_TYPE_TAG,
319 : : .funct = add_meta_tag,
320 : : },
321 : : {
322 : : .mask = RTE_FLOW_ITEM_TYPE_ETH,
323 : : .funct = add_ether,
324 : : },
325 : : {
326 : : .mask = RTE_FLOW_ITEM_TYPE_VLAN,
327 : : .funct = add_vlan,
328 : : },
329 : : {
330 : : .mask = RTE_FLOW_ITEM_TYPE_IPV4,
331 : : .funct = add_ipv4,
332 : : },
333 : : {
334 : : .mask = RTE_FLOW_ITEM_TYPE_IPV6,
335 : : .funct = add_ipv6,
336 : : },
337 : : {
338 : : .mask = RTE_FLOW_ITEM_TYPE_TCP,
339 : : .funct = add_tcp,
340 : : },
341 : : {
342 : : .mask = RTE_FLOW_ITEM_TYPE_UDP,
343 : : .funct = add_udp,
344 : : },
345 : : {
346 : : .mask = RTE_FLOW_ITEM_TYPE_VXLAN,
347 : : .funct = add_vxlan,
348 : : },
349 : : {
350 : : .mask = RTE_FLOW_ITEM_TYPE_VXLAN_GPE,
351 : : .funct = add_vxlan_gpe,
352 : : },
353 : : {
354 : : .mask = RTE_FLOW_ITEM_TYPE_GRE,
355 : : .funct = add_gre,
356 : : },
357 : : {
358 : : .mask = RTE_FLOW_ITEM_TYPE_GENEVE,
359 : : .funct = add_geneve,
360 : : },
361 : : {
362 : : .mask = RTE_FLOW_ITEM_TYPE_GTP,
363 : : .funct = add_gtp,
364 : : },
365 : : {
366 : : .mask = RTE_FLOW_ITEM_TYPE_ICMP,
367 : : .funct = add_icmpv4,
368 : : },
369 : : {
370 : : .mask = RTE_FLOW_ITEM_TYPE_ICMP6,
371 : : .funct = add_icmpv6,
372 : : },
373 : : };
374 : :
375 : 0 : for (j = 0; j < MAX_ITEMS_NUM; j++) {
376 : 0 : if (flow_items[j] == 0)
377 : : break;
378 : 0 : for (i = 0; i < RTE_DIM(items_list); i++) {
379 : 0 : if ((flow_items[j] &
380 : 0 : FLOW_ITEM_MASK(items_list[i].mask)) == 0)
381 : : continue;
382 : 0 : items_list[i].funct(
383 : 0 : items, items_counter++,
384 : : additional_para_data
385 : : );
386 : 0 : break;
387 : : }
388 : : }
389 : :
390 : 0 : items[items_counter].type = RTE_FLOW_ITEM_TYPE_END;
391 : 0 : }
|