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