]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/dpdk/drivers/net/mvpp2/mrvl_flow.c
import 15.2.0 Octopus source
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / mvpp2 / mrvl_flow.c
CommitLineData
11fdf7f2
TL
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Marvell International Ltd.
3 * Copyright(c) 2018 Semihalf.
4 * All rights reserved.
5 */
6
7#include <rte_flow.h>
8#include <rte_flow_driver.h>
9#include <rte_malloc.h>
10#include <rte_log.h>
11
12#include <arpa/inet.h>
13
9f95a23c 14#include "mrvl_flow.h"
11fdf7f2 15#include "mrvl_qos.h"
11fdf7f2
TL
16
17/** Number of rules in the classifier table. */
18#define MRVL_CLS_MAX_NUM_RULES 20
19
20/** Size of the classifier key and mask strings. */
21#define MRVL_CLS_STR_SIZE_MAX 40
22
11fdf7f2
TL
23static const enum rte_flow_item_type pattern_eth[] = {
24 RTE_FLOW_ITEM_TYPE_ETH,
25 RTE_FLOW_ITEM_TYPE_END
26};
27
28static const enum rte_flow_item_type pattern_eth_vlan[] = {
29 RTE_FLOW_ITEM_TYPE_ETH,
30 RTE_FLOW_ITEM_TYPE_VLAN,
31 RTE_FLOW_ITEM_TYPE_END
32};
33
34static const enum rte_flow_item_type pattern_eth_vlan_ip[] = {
35 RTE_FLOW_ITEM_TYPE_ETH,
36 RTE_FLOW_ITEM_TYPE_VLAN,
37 RTE_FLOW_ITEM_TYPE_IPV4,
38 RTE_FLOW_ITEM_TYPE_END
39};
40
41static const enum rte_flow_item_type pattern_eth_vlan_ip6[] = {
42 RTE_FLOW_ITEM_TYPE_ETH,
43 RTE_FLOW_ITEM_TYPE_VLAN,
44 RTE_FLOW_ITEM_TYPE_IPV6,
45 RTE_FLOW_ITEM_TYPE_END
46};
47
48static const enum rte_flow_item_type pattern_eth_ip4[] = {
49 RTE_FLOW_ITEM_TYPE_ETH,
50 RTE_FLOW_ITEM_TYPE_IPV4,
51 RTE_FLOW_ITEM_TYPE_END
52};
53
54static const enum rte_flow_item_type pattern_eth_ip4_tcp[] = {
55 RTE_FLOW_ITEM_TYPE_ETH,
56 RTE_FLOW_ITEM_TYPE_IPV4,
57 RTE_FLOW_ITEM_TYPE_TCP,
58 RTE_FLOW_ITEM_TYPE_END
59};
60
61static const enum rte_flow_item_type pattern_eth_ip4_udp[] = {
62 RTE_FLOW_ITEM_TYPE_ETH,
63 RTE_FLOW_ITEM_TYPE_IPV4,
64 RTE_FLOW_ITEM_TYPE_UDP,
65 RTE_FLOW_ITEM_TYPE_END
66};
67
68static const enum rte_flow_item_type pattern_eth_ip6[] = {
69 RTE_FLOW_ITEM_TYPE_ETH,
70 RTE_FLOW_ITEM_TYPE_IPV6,
71 RTE_FLOW_ITEM_TYPE_END
72};
73
74static const enum rte_flow_item_type pattern_eth_ip6_tcp[] = {
75 RTE_FLOW_ITEM_TYPE_ETH,
76 RTE_FLOW_ITEM_TYPE_IPV6,
77 RTE_FLOW_ITEM_TYPE_TCP,
78 RTE_FLOW_ITEM_TYPE_END
79};
80
81static const enum rte_flow_item_type pattern_eth_ip6_udp[] = {
82 RTE_FLOW_ITEM_TYPE_ETH,
83 RTE_FLOW_ITEM_TYPE_IPV6,
84 RTE_FLOW_ITEM_TYPE_UDP,
85 RTE_FLOW_ITEM_TYPE_END
86};
87
88static const enum rte_flow_item_type pattern_vlan[] = {
89 RTE_FLOW_ITEM_TYPE_VLAN,
90 RTE_FLOW_ITEM_TYPE_END
91};
92
93static const enum rte_flow_item_type pattern_vlan_ip[] = {
94 RTE_FLOW_ITEM_TYPE_VLAN,
95 RTE_FLOW_ITEM_TYPE_IPV4,
96 RTE_FLOW_ITEM_TYPE_END
97};
98
99static const enum rte_flow_item_type pattern_vlan_ip_tcp[] = {
100 RTE_FLOW_ITEM_TYPE_VLAN,
101 RTE_FLOW_ITEM_TYPE_IPV4,
102 RTE_FLOW_ITEM_TYPE_TCP,
103 RTE_FLOW_ITEM_TYPE_END
104};
105
106static const enum rte_flow_item_type pattern_vlan_ip_udp[] = {
107 RTE_FLOW_ITEM_TYPE_VLAN,
108 RTE_FLOW_ITEM_TYPE_IPV4,
109 RTE_FLOW_ITEM_TYPE_UDP,
110 RTE_FLOW_ITEM_TYPE_END
111};
112
113static const enum rte_flow_item_type pattern_vlan_ip6[] = {
114 RTE_FLOW_ITEM_TYPE_VLAN,
115 RTE_FLOW_ITEM_TYPE_IPV6,
116 RTE_FLOW_ITEM_TYPE_END
117};
118
119static const enum rte_flow_item_type pattern_vlan_ip6_tcp[] = {
120 RTE_FLOW_ITEM_TYPE_VLAN,
121 RTE_FLOW_ITEM_TYPE_IPV6,
122 RTE_FLOW_ITEM_TYPE_TCP,
123 RTE_FLOW_ITEM_TYPE_END
124};
125
126static const enum rte_flow_item_type pattern_vlan_ip6_udp[] = {
127 RTE_FLOW_ITEM_TYPE_VLAN,
128 RTE_FLOW_ITEM_TYPE_IPV6,
129 RTE_FLOW_ITEM_TYPE_UDP,
130 RTE_FLOW_ITEM_TYPE_END
131};
132
133static const enum rte_flow_item_type pattern_ip[] = {
134 RTE_FLOW_ITEM_TYPE_IPV4,
135 RTE_FLOW_ITEM_TYPE_END
136};
137
138static const enum rte_flow_item_type pattern_ip6[] = {
139 RTE_FLOW_ITEM_TYPE_IPV6,
140 RTE_FLOW_ITEM_TYPE_END
141};
142
143static const enum rte_flow_item_type pattern_ip_tcp[] = {
144 RTE_FLOW_ITEM_TYPE_IPV4,
145 RTE_FLOW_ITEM_TYPE_TCP,
146 RTE_FLOW_ITEM_TYPE_END
147};
148
149static const enum rte_flow_item_type pattern_ip6_tcp[] = {
150 RTE_FLOW_ITEM_TYPE_IPV6,
151 RTE_FLOW_ITEM_TYPE_TCP,
152 RTE_FLOW_ITEM_TYPE_END
153};
154
155static const enum rte_flow_item_type pattern_ip_udp[] = {
156 RTE_FLOW_ITEM_TYPE_IPV4,
157 RTE_FLOW_ITEM_TYPE_UDP,
158 RTE_FLOW_ITEM_TYPE_END
159};
160
161static const enum rte_flow_item_type pattern_ip6_udp[] = {
162 RTE_FLOW_ITEM_TYPE_IPV6,
163 RTE_FLOW_ITEM_TYPE_UDP,
164 RTE_FLOW_ITEM_TYPE_END
165};
166
167static const enum rte_flow_item_type pattern_tcp[] = {
168 RTE_FLOW_ITEM_TYPE_TCP,
169 RTE_FLOW_ITEM_TYPE_END
170};
171
172static const enum rte_flow_item_type pattern_udp[] = {
173 RTE_FLOW_ITEM_TYPE_UDP,
174 RTE_FLOW_ITEM_TYPE_END
175};
176
177#define MRVL_VLAN_ID_MASK 0x0fff
178#define MRVL_VLAN_PRI_MASK 0x7000
179#define MRVL_IPV4_DSCP_MASK 0xfc
180#define MRVL_IPV4_ADDR_MASK 0xffffffff
181#define MRVL_IPV6_FLOW_MASK 0x0fffff
182
183/**
184 * Given a flow item, return the next non-void one.
185 *
186 * @param items Pointer to the item in the table.
187 * @returns Next not-void item, NULL otherwise.
188 */
189static const struct rte_flow_item *
190mrvl_next_item(const struct rte_flow_item *items)
191{
192 const struct rte_flow_item *item = items;
193
194 for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
195 if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
196 return item;
197 }
198
199 return NULL;
200}
201
202/**
203 * Allocate memory for classifier rule key and mask fields.
204 *
205 * @param field Pointer to the classifier rule.
206 * @returns 0 in case of success, negative value otherwise.
207 */
208static int
209mrvl_alloc_key_mask(struct pp2_cls_rule_key_field *field)
210{
211 unsigned int id = rte_socket_id();
212
213 field->key = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id);
214 if (!field->key)
215 goto out;
216
217 field->mask = rte_zmalloc_socket(NULL, MRVL_CLS_STR_SIZE_MAX, 0, id);
218 if (!field->mask)
219 goto out_mask;
220
221 return 0;
222out_mask:
223 rte_free(field->key);
224out:
225 field->key = NULL;
226 field->mask = NULL;
227 return -1;
228}
229
230/**
231 * Free memory allocated for classifier rule key and mask fields.
232 *
233 * @param field Pointer to the classifier rule.
234 */
235static void
236mrvl_free_key_mask(struct pp2_cls_rule_key_field *field)
237{
238 rte_free(field->key);
239 rte_free(field->mask);
240 field->key = NULL;
241 field->mask = NULL;
242}
243
244/**
245 * Free memory allocated for all classifier rule key and mask fields.
246 *
247 * @param rule Pointer to the classifier table rule.
248 */
249static void
250mrvl_free_all_key_mask(struct pp2_cls_tbl_rule *rule)
251{
252 int i;
253
254 for (i = 0; i < rule->num_fields; i++)
255 mrvl_free_key_mask(&rule->fields[i]);
256 rule->num_fields = 0;
257}
258
259/*
260 * Initialize rte flow item parsing.
261 *
262 * @param item Pointer to the flow item.
263 * @param spec_ptr Pointer to the specific item pointer.
264 * @param mask_ptr Pointer to the specific item's mask pointer.
265 * @def_mask Pointer to the default mask.
266 * @size Size of the flow item.
267 * @error Pointer to the rte flow error.
268 * @returns 0 in case of success, negative value otherwise.
269 */
270static int
271mrvl_parse_init(const struct rte_flow_item *item,
272 const void **spec_ptr,
273 const void **mask_ptr,
274 const void *def_mask,
275 unsigned int size,
276 struct rte_flow_error *error)
277{
278 const uint8_t *spec;
279 const uint8_t *mask;
280 const uint8_t *last;
281 uint8_t zeros[size];
282
283 memset(zeros, 0, size);
284
285 if (item == NULL) {
286 rte_flow_error_set(error, EINVAL,
287 RTE_FLOW_ERROR_TYPE_ITEM, NULL,
288 "NULL item\n");
289 return -rte_errno;
290 }
291
292 if ((item->last != NULL || item->mask != NULL) && item->spec == NULL) {
293 rte_flow_error_set(error, EINVAL,
294 RTE_FLOW_ERROR_TYPE_ITEM, item,
295 "Mask or last is set without spec\n");
296 return -rte_errno;
297 }
298
299 /*
300 * If "mask" is not set, default mask is used,
301 * but if default mask is NULL, "mask" should be set.
302 */
303 if (item->mask == NULL) {
304 if (def_mask == NULL) {
305 rte_flow_error_set(error, EINVAL,
306 RTE_FLOW_ERROR_TYPE_ITEM, NULL,
307 "Mask should be specified\n");
308 return -rte_errno;
309 }
310
311 mask = (const uint8_t *)def_mask;
312 } else {
313 mask = (const uint8_t *)item->mask;
314 }
315
316 spec = (const uint8_t *)item->spec;
317 last = (const uint8_t *)item->last;
318
319 if (spec == NULL) {
320 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
321 NULL, "Spec should be specified\n");
322 return -rte_errno;
323 }
324
325 /*
326 * If field values in "last" are either 0 or equal to the corresponding
327 * values in "spec" then they are ignored.
328 */
329 if (last != NULL &&
330 !memcmp(last, zeros, size) &&
331 memcmp(last, spec, size) != 0) {
332 rte_flow_error_set(error, ENOTSUP,
333 RTE_FLOW_ERROR_TYPE_ITEM, NULL,
334 "Ranging is not supported\n");
335 return -rte_errno;
336 }
337
338 *spec_ptr = spec;
339 *mask_ptr = mask;
340
341 return 0;
342}
343
344/**
345 * Parse the eth flow item.
346 *
347 * This will create classifier rule that matches either destination or source
348 * mac.
349 *
350 * @param spec Pointer to the specific flow item.
351 * @param mask Pointer to the specific flow item's mask.
9f95a23c
TL
352 * @param parse_dst Parse either destination or source mac address.
353 * @param flow Pointer to the flow.
11fdf7f2
TL
354 * @return 0 in case of success, negative error value otherwise.
355 */
356static int
357mrvl_parse_mac(const struct rte_flow_item_eth *spec,
358 const struct rte_flow_item_eth *mask,
359 int parse_dst, struct rte_flow *flow)
360{
361 struct pp2_cls_rule_key_field *key_field;
362 const uint8_t *k, *m;
363
364 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
365 return -ENOSPC;
366
367 if (parse_dst) {
368 k = spec->dst.addr_bytes;
369 m = mask->dst.addr_bytes;
370
371 flow->pattern |= F_DMAC;
372 } else {
373 k = spec->src.addr_bytes;
374 m = mask->src.addr_bytes;
375
376 flow->pattern |= F_SMAC;
377 }
378
379 key_field = &flow->rule.fields[flow->rule.num_fields];
380 mrvl_alloc_key_mask(key_field);
381 key_field->size = 6;
382
383 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX,
384 "%02x:%02x:%02x:%02x:%02x:%02x",
385 k[0], k[1], k[2], k[3], k[4], k[5]);
386
387 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX,
388 "%02x:%02x:%02x:%02x:%02x:%02x",
389 m[0], m[1], m[2], m[3], m[4], m[5]);
390
391 flow->rule.num_fields += 1;
392
393 return 0;
394}
395
396/**
397 * Helper for parsing the eth flow item destination mac address.
398 *
399 * @param spec Pointer to the specific flow item.
400 * @param mask Pointer to the specific flow item's mask.
401 * @param flow Pointer to the flow.
402 * @return 0 in case of success, negative error value otherwise.
403 */
404static inline int
405mrvl_parse_dmac(const struct rte_flow_item_eth *spec,
406 const struct rte_flow_item_eth *mask,
407 struct rte_flow *flow)
408{
409 return mrvl_parse_mac(spec, mask, 1, flow);
410}
411
412/**
413 * Helper for parsing the eth flow item source mac address.
414 *
415 * @param spec Pointer to the specific flow item.
416 * @param mask Pointer to the specific flow item's mask.
417 * @param flow Pointer to the flow.
418 * @return 0 in case of success, negative error value otherwise.
419 */
420static inline int
421mrvl_parse_smac(const struct rte_flow_item_eth *spec,
422 const struct rte_flow_item_eth *mask,
423 struct rte_flow *flow)
424{
425 return mrvl_parse_mac(spec, mask, 0, flow);
426}
427
428/**
429 * Parse the ether type field of the eth flow item.
430 *
431 * @param spec Pointer to the specific flow item.
432 * @param mask Pointer to the specific flow item's mask.
433 * @param flow Pointer to the flow.
434 * @return 0 in case of success, negative error value otherwise.
435 */
436static int
437mrvl_parse_type(const struct rte_flow_item_eth *spec,
438 const struct rte_flow_item_eth *mask __rte_unused,
439 struct rte_flow *flow)
440{
441 struct pp2_cls_rule_key_field *key_field;
442 uint16_t k;
443
444 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
445 return -ENOSPC;
446
447 key_field = &flow->rule.fields[flow->rule.num_fields];
448 mrvl_alloc_key_mask(key_field);
449 key_field->size = 2;
450
451 k = rte_be_to_cpu_16(spec->type);
452 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
453
454 flow->pattern |= F_TYPE;
455 flow->rule.num_fields += 1;
456
457 return 0;
458}
459
460/**
461 * Parse the vid field of the vlan rte flow item.
462 *
463 * This will create classifier rule that matches vid.
464 *
465 * @param spec Pointer to the specific flow item.
466 * @param mask Pointer to the specific flow item's mask.
467 * @param flow Pointer to the flow.
468 * @return 0 in case of success, negative error value otherwise.
469 */
470static int
471mrvl_parse_vlan_id(const struct rte_flow_item_vlan *spec,
472 const struct rte_flow_item_vlan *mask __rte_unused,
473 struct rte_flow *flow)
474{
475 struct pp2_cls_rule_key_field *key_field;
476 uint16_t k;
477
478 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
479 return -ENOSPC;
480
481 key_field = &flow->rule.fields[flow->rule.num_fields];
482 mrvl_alloc_key_mask(key_field);
483 key_field->size = 2;
484
485 k = rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_ID_MASK;
486 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
487
488 flow->pattern |= F_VLAN_ID;
489 flow->rule.num_fields += 1;
490
491 return 0;
492}
493
494/**
495 * Parse the pri field of the vlan rte flow item.
496 *
497 * This will create classifier rule that matches pri.
498 *
499 * @param spec Pointer to the specific flow item.
500 * @param mask Pointer to the specific flow item's mask.
501 * @param flow Pointer to the flow.
502 * @return 0 in case of success, negative error value otherwise.
503 */
504static int
505mrvl_parse_vlan_pri(const struct rte_flow_item_vlan *spec,
506 const struct rte_flow_item_vlan *mask __rte_unused,
507 struct rte_flow *flow)
508{
509 struct pp2_cls_rule_key_field *key_field;
510 uint16_t k;
511
512 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
513 return -ENOSPC;
514
515 key_field = &flow->rule.fields[flow->rule.num_fields];
516 mrvl_alloc_key_mask(key_field);
517 key_field->size = 1;
518
519 k = (rte_be_to_cpu_16(spec->tci) & MRVL_VLAN_PRI_MASK) >> 13;
520 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
521
522 flow->pattern |= F_VLAN_PRI;
523 flow->rule.num_fields += 1;
524
525 return 0;
526}
527
528/**
529 * Parse the dscp field of the ipv4 rte flow item.
530 *
531 * This will create classifier rule that matches dscp field.
532 *
533 * @param spec Pointer to the specific flow item.
534 * @param mask Pointer to the specific flow item's mask.
535 * @param flow Pointer to the flow.
536 * @return 0 in case of success, negative error value otherwise.
537 */
538static int
539mrvl_parse_ip4_dscp(const struct rte_flow_item_ipv4 *spec,
540 const struct rte_flow_item_ipv4 *mask,
541 struct rte_flow *flow)
542{
543 struct pp2_cls_rule_key_field *key_field;
544 uint8_t k, m;
545
546 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
547 return -ENOSPC;
548
549 key_field = &flow->rule.fields[flow->rule.num_fields];
550 mrvl_alloc_key_mask(key_field);
551 key_field->size = 1;
552
553 k = (spec->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2;
554 m = (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) >> 2;
555 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
556 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m);
557
558 flow->pattern |= F_IP4_TOS;
559 flow->rule.num_fields += 1;
560
561 return 0;
562}
563
564/**
565 * Parse either source or destination ip addresses of the ipv4 flow item.
566 *
567 * This will create classifier rule that matches either destination
568 * or source ip field.
569 *
570 * @param spec Pointer to the specific flow item.
571 * @param mask Pointer to the specific flow item's mask.
9f95a23c 572 * @param parse_dst Parse either destination or source ip address.
11fdf7f2
TL
573 * @param flow Pointer to the flow.
574 * @return 0 in case of success, negative error value otherwise.
575 */
576static int
577mrvl_parse_ip4_addr(const struct rte_flow_item_ipv4 *spec,
578 const struct rte_flow_item_ipv4 *mask,
579 int parse_dst, struct rte_flow *flow)
580{
581 struct pp2_cls_rule_key_field *key_field;
582 struct in_addr k;
583 uint32_t m;
584
585 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
586 return -ENOSPC;
587
588 memset(&k, 0, sizeof(k));
589 if (parse_dst) {
590 k.s_addr = spec->hdr.dst_addr;
591 m = rte_be_to_cpu_32(mask->hdr.dst_addr);
592
593 flow->pattern |= F_IP4_DIP;
594 } else {
595 k.s_addr = spec->hdr.src_addr;
596 m = rte_be_to_cpu_32(mask->hdr.src_addr);
597
598 flow->pattern |= F_IP4_SIP;
599 }
600
601 key_field = &flow->rule.fields[flow->rule.num_fields];
602 mrvl_alloc_key_mask(key_field);
603 key_field->size = 4;
604
605 inet_ntop(AF_INET, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX);
606 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "0x%x", m);
607
608 flow->rule.num_fields += 1;
609
610 return 0;
611}
612
613/**
614 * Helper for parsing destination ip of the ipv4 flow item.
615 *
616 * @param spec Pointer to the specific flow item.
617 * @param mask Pointer to the specific flow item's mask.
618 * @param flow Pointer to the flow.
619 * @return 0 in case of success, negative error value otherwise.
620 */
621static inline int
622mrvl_parse_ip4_dip(const struct rte_flow_item_ipv4 *spec,
623 const struct rte_flow_item_ipv4 *mask,
624 struct rte_flow *flow)
625{
626 return mrvl_parse_ip4_addr(spec, mask, 1, flow);
627}
628
629/**
630 * Helper for parsing source ip of the ipv4 flow item.
631 *
632 * @param spec Pointer to the specific flow item.
633 * @param mask Pointer to the specific flow item's mask.
634 * @param flow Pointer to the flow.
635 * @return 0 in case of success, negative error value otherwise.
636 */
637static inline int
638mrvl_parse_ip4_sip(const struct rte_flow_item_ipv4 *spec,
639 const struct rte_flow_item_ipv4 *mask,
640 struct rte_flow *flow)
641{
642 return mrvl_parse_ip4_addr(spec, mask, 0, flow);
643}
644
645/**
646 * Parse the proto field of the ipv4 rte flow item.
647 *
648 * This will create classifier rule that matches proto field.
649 *
650 * @param spec Pointer to the specific flow item.
651 * @param mask Pointer to the specific flow item's mask.
652 * @param flow Pointer to the flow.
653 * @return 0 in case of success, negative error value otherwise.
654 */
655static int
656mrvl_parse_ip4_proto(const struct rte_flow_item_ipv4 *spec,
657 const struct rte_flow_item_ipv4 *mask __rte_unused,
658 struct rte_flow *flow)
659{
660 struct pp2_cls_rule_key_field *key_field;
661 uint8_t k = spec->hdr.next_proto_id;
662
663 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
664 return -ENOSPC;
665
666 key_field = &flow->rule.fields[flow->rule.num_fields];
667 mrvl_alloc_key_mask(key_field);
668 key_field->size = 1;
669
670 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
671
672 flow->pattern |= F_IP4_PROTO;
673 flow->rule.num_fields += 1;
674
675 return 0;
676}
677
678/**
679 * Parse either source or destination ip addresses of the ipv6 rte flow item.
680 *
681 * This will create classifier rule that matches either destination
682 * or source ip field.
683 *
684 * @param spec Pointer to the specific flow item.
685 * @param mask Pointer to the specific flow item's mask.
9f95a23c 686 * @param parse_dst Parse either destination or source ipv6 address.
11fdf7f2
TL
687 * @param flow Pointer to the flow.
688 * @return 0 in case of success, negative error value otherwise.
689 */
690static int
691mrvl_parse_ip6_addr(const struct rte_flow_item_ipv6 *spec,
692 const struct rte_flow_item_ipv6 *mask,
693 int parse_dst, struct rte_flow *flow)
694{
695 struct pp2_cls_rule_key_field *key_field;
696 int size = sizeof(spec->hdr.dst_addr);
697 struct in6_addr k, m;
698
699 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
700 return -ENOSPC;
701
702 memset(&k, 0, sizeof(k));
703 if (parse_dst) {
704 memcpy(k.s6_addr, spec->hdr.dst_addr, size);
705 memcpy(m.s6_addr, mask->hdr.dst_addr, size);
706
707 flow->pattern |= F_IP6_DIP;
708 } else {
709 memcpy(k.s6_addr, spec->hdr.src_addr, size);
710 memcpy(m.s6_addr, mask->hdr.src_addr, size);
711
712 flow->pattern |= F_IP6_SIP;
713 }
714
715 key_field = &flow->rule.fields[flow->rule.num_fields];
716 mrvl_alloc_key_mask(key_field);
717 key_field->size = 16;
718
719 inet_ntop(AF_INET6, &k, (char *)key_field->key, MRVL_CLS_STR_SIZE_MAX);
720 inet_ntop(AF_INET6, &m, (char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX);
721
722 flow->rule.num_fields += 1;
723
724 return 0;
725}
726
727/**
728 * Helper for parsing destination ip of the ipv6 flow item.
729 *
730 * @param spec Pointer to the specific flow item.
731 * @param mask Pointer to the specific flow item's mask.
732 * @param flow Pointer to the flow.
733 * @return 0 in case of success, negative error value otherwise.
734 */
735static inline int
736mrvl_parse_ip6_dip(const struct rte_flow_item_ipv6 *spec,
737 const struct rte_flow_item_ipv6 *mask,
738 struct rte_flow *flow)
739{
740 return mrvl_parse_ip6_addr(spec, mask, 1, flow);
741}
742
743/**
744 * Helper for parsing source ip of the ipv6 flow item.
745 *
746 * @param spec Pointer to the specific flow item.
747 * @param mask Pointer to the specific flow item's mask.
748 * @param flow Pointer to the flow.
749 * @return 0 in case of success, negative error value otherwise.
750 */
751static inline int
752mrvl_parse_ip6_sip(const struct rte_flow_item_ipv6 *spec,
753 const struct rte_flow_item_ipv6 *mask,
754 struct rte_flow *flow)
755{
756 return mrvl_parse_ip6_addr(spec, mask, 0, flow);
757}
758
759/**
760 * Parse the flow label of the ipv6 flow item.
761 *
762 * This will create classifier rule that matches flow field.
763 *
764 * @param spec Pointer to the specific flow item.
765 * @param mask Pointer to the specific flow item's mask.
766 * @param flow Pointer to the flow.
767 * @return 0 in case of success, negative error value otherwise.
768 */
769static int
770mrvl_parse_ip6_flow(const struct rte_flow_item_ipv6 *spec,
771 const struct rte_flow_item_ipv6 *mask,
772 struct rte_flow *flow)
773{
774 struct pp2_cls_rule_key_field *key_field;
775 uint32_t k = rte_be_to_cpu_32(spec->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK,
776 m = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK;
777
778 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
779 return -ENOSPC;
780
781 key_field = &flow->rule.fields[flow->rule.num_fields];
782 mrvl_alloc_key_mask(key_field);
783 key_field->size = 3;
784
785 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
786 snprintf((char *)key_field->mask, MRVL_CLS_STR_SIZE_MAX, "%u", m);
787
788 flow->pattern |= F_IP6_FLOW;
789 flow->rule.num_fields += 1;
790
791 return 0;
792}
793
794/**
795 * Parse the next header of the ipv6 flow item.
796 *
797 * This will create classifier rule that matches next header field.
798 *
799 * @param spec Pointer to the specific flow item.
800 * @param mask Pointer to the specific flow item's mask.
801 * @param flow Pointer to the flow.
802 * @return 0 in case of success, negative error value otherwise.
803 */
804static int
805mrvl_parse_ip6_next_hdr(const struct rte_flow_item_ipv6 *spec,
806 const struct rte_flow_item_ipv6 *mask __rte_unused,
807 struct rte_flow *flow)
808{
809 struct pp2_cls_rule_key_field *key_field;
810 uint8_t k = spec->hdr.proto;
811
812 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
813 return -ENOSPC;
814
815 key_field = &flow->rule.fields[flow->rule.num_fields];
816 mrvl_alloc_key_mask(key_field);
817 key_field->size = 1;
818
819 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
820
821 flow->pattern |= F_IP6_NEXT_HDR;
822 flow->rule.num_fields += 1;
823
824 return 0;
825}
826
827/**
828 * Parse destination or source port of the tcp flow item.
829 *
830 * This will create classifier rule that matches either destination or
831 * source tcp port.
832 *
833 * @param spec Pointer to the specific flow item.
834 * @param mask Pointer to the specific flow item's mask.
9f95a23c 835 * @param parse_dst Parse either destination or source port.
11fdf7f2
TL
836 * @param flow Pointer to the flow.
837 * @return 0 in case of success, negative error value otherwise.
838 */
839static int
840mrvl_parse_tcp_port(const struct rte_flow_item_tcp *spec,
841 const struct rte_flow_item_tcp *mask __rte_unused,
842 int parse_dst, struct rte_flow *flow)
843{
844 struct pp2_cls_rule_key_field *key_field;
845 uint16_t k;
846
847 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
848 return -ENOSPC;
849
850 key_field = &flow->rule.fields[flow->rule.num_fields];
851 mrvl_alloc_key_mask(key_field);
852 key_field->size = 2;
853
854 if (parse_dst) {
855 k = rte_be_to_cpu_16(spec->hdr.dst_port);
856
857 flow->pattern |= F_TCP_DPORT;
858 } else {
859 k = rte_be_to_cpu_16(spec->hdr.src_port);
860
861 flow->pattern |= F_TCP_SPORT;
862 }
863
864 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
865
866 flow->rule.num_fields += 1;
867
868 return 0;
869}
870
871/**
872 * Helper for parsing the tcp source port of the tcp flow item.
873 *
874 * @param spec Pointer to the specific flow item.
875 * @param mask Pointer to the specific flow item's mask.
876 * @param flow Pointer to the flow.
877 * @return 0 in case of success, negative error value otherwise.
878 */
879static inline int
880mrvl_parse_tcp_sport(const struct rte_flow_item_tcp *spec,
881 const struct rte_flow_item_tcp *mask,
882 struct rte_flow *flow)
883{
884 return mrvl_parse_tcp_port(spec, mask, 0, flow);
885}
886
887/**
888 * Helper for parsing the tcp destination port of the tcp flow item.
889 *
890 * @param spec Pointer to the specific flow item.
891 * @param mask Pointer to the specific flow item's mask.
892 * @param flow Pointer to the flow.
893 * @return 0 in case of success, negative error value otherwise.
894 */
895static inline int
896mrvl_parse_tcp_dport(const struct rte_flow_item_tcp *spec,
897 const struct rte_flow_item_tcp *mask,
898 struct rte_flow *flow)
899{
900 return mrvl_parse_tcp_port(spec, mask, 1, flow);
901}
902
903/**
904 * Parse destination or source port of the udp flow item.
905 *
906 * This will create classifier rule that matches either destination or
907 * source udp port.
908 *
909 * @param spec Pointer to the specific flow item.
910 * @param mask Pointer to the specific flow item's mask.
9f95a23c 911 * @param parse_dst Parse either destination or source port.
11fdf7f2
TL
912 * @param flow Pointer to the flow.
913 * @return 0 in case of success, negative error value otherwise.
914 */
915static int
916mrvl_parse_udp_port(const struct rte_flow_item_udp *spec,
917 const struct rte_flow_item_udp *mask __rte_unused,
918 int parse_dst, struct rte_flow *flow)
919{
920 struct pp2_cls_rule_key_field *key_field;
921 uint16_t k;
922
923 if (flow->rule.num_fields >= PP2_CLS_TBL_MAX_NUM_FIELDS)
924 return -ENOSPC;
925
926 key_field = &flow->rule.fields[flow->rule.num_fields];
927 mrvl_alloc_key_mask(key_field);
928 key_field->size = 2;
929
930 if (parse_dst) {
931 k = rte_be_to_cpu_16(spec->hdr.dst_port);
932
933 flow->pattern |= F_UDP_DPORT;
934 } else {
935 k = rte_be_to_cpu_16(spec->hdr.src_port);
936
937 flow->pattern |= F_UDP_SPORT;
938 }
939
940 snprintf((char *)key_field->key, MRVL_CLS_STR_SIZE_MAX, "%u", k);
941
942 flow->rule.num_fields += 1;
943
944 return 0;
945}
946
947/**
948 * Helper for parsing the udp source port of the udp flow item.
949 *
950 * @param spec Pointer to the specific flow item.
951 * @param mask Pointer to the specific flow item's mask.
952 * @param flow Pointer to the flow.
953 * @return 0 in case of success, negative error value otherwise.
954 */
955static inline int
956mrvl_parse_udp_sport(const struct rte_flow_item_udp *spec,
957 const struct rte_flow_item_udp *mask,
958 struct rte_flow *flow)
959{
960 return mrvl_parse_udp_port(spec, mask, 0, flow);
961}
962
963/**
964 * Helper for parsing the udp destination port of the udp flow item.
965 *
966 * @param spec Pointer to the specific flow item.
967 * @param mask Pointer to the specific flow item's mask.
968 * @param flow Pointer to the flow.
969 * @return 0 in case of success, negative error value otherwise.
970 */
971static inline int
972mrvl_parse_udp_dport(const struct rte_flow_item_udp *spec,
973 const struct rte_flow_item_udp *mask,
974 struct rte_flow *flow)
975{
976 return mrvl_parse_udp_port(spec, mask, 1, flow);
977}
978
979/**
980 * Parse eth flow item.
981 *
982 * @param item Pointer to the flow item.
983 * @param flow Pointer to the flow.
984 * @param error Pointer to the flow error.
11fdf7f2
TL
985 * @returns 0 on success, negative value otherwise.
986 */
987static int
988mrvl_parse_eth(const struct rte_flow_item *item, struct rte_flow *flow,
989 struct rte_flow_error *error)
990{
991 const struct rte_flow_item_eth *spec = NULL, *mask = NULL;
992 struct ether_addr zero;
993 int ret;
994
995 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
996 &rte_flow_item_eth_mask,
997 sizeof(struct rte_flow_item_eth), error);
998 if (ret)
999 return ret;
1000
1001 memset(&zero, 0, sizeof(zero));
1002
1003 if (memcmp(&mask->dst, &zero, sizeof(mask->dst))) {
1004 ret = mrvl_parse_dmac(spec, mask, flow);
1005 if (ret)
1006 goto out;
1007 }
1008
1009 if (memcmp(&mask->src, &zero, sizeof(mask->src))) {
1010 ret = mrvl_parse_smac(spec, mask, flow);
1011 if (ret)
1012 goto out;
1013 }
1014
1015 if (mask->type) {
1016 MRVL_LOG(WARNING, "eth type mask is ignored");
1017 ret = mrvl_parse_type(spec, mask, flow);
1018 if (ret)
1019 goto out;
1020 }
1021
1022 return 0;
1023out:
1024 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1025 "Reached maximum number of fields in cls tbl key\n");
1026 return -rte_errno;
1027}
1028
1029/**
1030 * Parse vlan flow item.
1031 *
1032 * @param item Pointer to the flow item.
1033 * @param flow Pointer to the flow.
1034 * @param error Pointer to the flow error.
11fdf7f2
TL
1035 * @returns 0 on success, negative value otherwise.
1036 */
1037static int
1038mrvl_parse_vlan(const struct rte_flow_item *item,
1039 struct rte_flow *flow,
1040 struct rte_flow_error *error)
1041{
1042 const struct rte_flow_item_vlan *spec = NULL, *mask = NULL;
1043 uint16_t m;
1044 int ret;
1045
1046 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1047 &rte_flow_item_vlan_mask,
1048 sizeof(struct rte_flow_item_vlan), error);
1049 if (ret)
1050 return ret;
1051
1052 m = rte_be_to_cpu_16(mask->tci);
1053 if (m & MRVL_VLAN_ID_MASK) {
1054 MRVL_LOG(WARNING, "vlan id mask is ignored");
1055 ret = mrvl_parse_vlan_id(spec, mask, flow);
1056 if (ret)
1057 goto out;
1058 }
1059
1060 if (m & MRVL_VLAN_PRI_MASK) {
1061 MRVL_LOG(WARNING, "vlan pri mask is ignored");
1062 ret = mrvl_parse_vlan_pri(spec, mask, flow);
1063 if (ret)
1064 goto out;
1065 }
1066
1067 if (flow->pattern & F_TYPE) {
1068 rte_flow_error_set(error, ENOTSUP,
1069 RTE_FLOW_ERROR_TYPE_ITEM, item,
1070 "VLAN TPID matching is not supported");
1071 return -rte_errno;
1072 }
1073 if (mask->inner_type) {
1074 struct rte_flow_item_eth spec_eth = {
1075 .type = spec->inner_type,
1076 };
1077 struct rte_flow_item_eth mask_eth = {
1078 .type = mask->inner_type,
1079 };
1080
1081 MRVL_LOG(WARNING, "inner eth type mask is ignored");
1082 ret = mrvl_parse_type(&spec_eth, &mask_eth, flow);
1083 if (ret)
1084 goto out;
1085 }
1086
1087 return 0;
1088out:
1089 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1090 "Reached maximum number of fields in cls tbl key\n");
1091 return -rte_errno;
1092}
1093
1094/**
1095 * Parse ipv4 flow item.
1096 *
1097 * @param item Pointer to the flow item.
1098 * @param flow Pointer to the flow.
1099 * @param error Pointer to the flow error.
11fdf7f2
TL
1100 * @returns 0 on success, negative value otherwise.
1101 */
1102static int
1103mrvl_parse_ip4(const struct rte_flow_item *item,
1104 struct rte_flow *flow,
1105 struct rte_flow_error *error)
1106{
1107 const struct rte_flow_item_ipv4 *spec = NULL, *mask = NULL;
1108 int ret;
1109
1110 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1111 &rte_flow_item_ipv4_mask,
1112 sizeof(struct rte_flow_item_ipv4), error);
1113 if (ret)
1114 return ret;
1115
1116 if (mask->hdr.version_ihl ||
1117 mask->hdr.total_length ||
1118 mask->hdr.packet_id ||
1119 mask->hdr.fragment_offset ||
1120 mask->hdr.time_to_live ||
1121 mask->hdr.hdr_checksum) {
1122 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1123 NULL, "Not supported by classifier\n");
1124 return -rte_errno;
1125 }
1126
1127 if (mask->hdr.type_of_service & MRVL_IPV4_DSCP_MASK) {
1128 ret = mrvl_parse_ip4_dscp(spec, mask, flow);
1129 if (ret)
1130 goto out;
1131 }
1132
1133 if (mask->hdr.src_addr) {
1134 ret = mrvl_parse_ip4_sip(spec, mask, flow);
1135 if (ret)
1136 goto out;
1137 }
1138
1139 if (mask->hdr.dst_addr) {
1140 ret = mrvl_parse_ip4_dip(spec, mask, flow);
1141 if (ret)
1142 goto out;
1143 }
1144
1145 if (mask->hdr.next_proto_id) {
1146 MRVL_LOG(WARNING, "next proto id mask is ignored");
1147 ret = mrvl_parse_ip4_proto(spec, mask, flow);
1148 if (ret)
1149 goto out;
1150 }
1151
1152 return 0;
1153out:
1154 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1155 "Reached maximum number of fields in cls tbl key\n");
1156 return -rte_errno;
1157}
1158
1159/**
1160 * Parse ipv6 flow item.
1161 *
1162 * @param item Pointer to the flow item.
1163 * @param flow Pointer to the flow.
1164 * @param error Pointer to the flow error.
11fdf7f2
TL
1165 * @returns 0 on success, negative value otherwise.
1166 */
1167static int
1168mrvl_parse_ip6(const struct rte_flow_item *item,
1169 struct rte_flow *flow,
1170 struct rte_flow_error *error)
1171{
1172 const struct rte_flow_item_ipv6 *spec = NULL, *mask = NULL;
1173 struct ipv6_hdr zero;
1174 uint32_t flow_mask;
1175 int ret;
1176
1177 ret = mrvl_parse_init(item, (const void **)&spec,
1178 (const void **)&mask,
1179 &rte_flow_item_ipv6_mask,
1180 sizeof(struct rte_flow_item_ipv6),
1181 error);
1182 if (ret)
1183 return ret;
1184
1185 memset(&zero, 0, sizeof(zero));
1186
1187 if (mask->hdr.payload_len ||
1188 mask->hdr.hop_limits) {
1189 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1190 NULL, "Not supported by classifier\n");
1191 return -rte_errno;
1192 }
1193
1194 if (memcmp(mask->hdr.src_addr,
1195 zero.src_addr, sizeof(mask->hdr.src_addr))) {
1196 ret = mrvl_parse_ip6_sip(spec, mask, flow);
1197 if (ret)
1198 goto out;
1199 }
1200
1201 if (memcmp(mask->hdr.dst_addr,
1202 zero.dst_addr, sizeof(mask->hdr.dst_addr))) {
1203 ret = mrvl_parse_ip6_dip(spec, mask, flow);
1204 if (ret)
1205 goto out;
1206 }
1207
1208 flow_mask = rte_be_to_cpu_32(mask->hdr.vtc_flow) & MRVL_IPV6_FLOW_MASK;
1209 if (flow_mask) {
1210 ret = mrvl_parse_ip6_flow(spec, mask, flow);
1211 if (ret)
1212 goto out;
1213 }
1214
1215 if (mask->hdr.proto) {
1216 MRVL_LOG(WARNING, "next header mask is ignored");
1217 ret = mrvl_parse_ip6_next_hdr(spec, mask, flow);
1218 if (ret)
1219 goto out;
1220 }
1221
1222 return 0;
1223out:
1224 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1225 "Reached maximum number of fields in cls tbl key\n");
1226 return -rte_errno;
1227}
1228
1229/**
1230 * Parse tcp flow item.
1231 *
1232 * @param item Pointer to the flow item.
1233 * @param flow Pointer to the flow.
1234 * @param error Pointer to the flow error.
11fdf7f2
TL
1235 * @returns 0 on success, negative value otherwise.
1236 */
1237static int
1238mrvl_parse_tcp(const struct rte_flow_item *item,
1239 struct rte_flow *flow,
1240 struct rte_flow_error *error)
1241{
1242 const struct rte_flow_item_tcp *spec = NULL, *mask = NULL;
1243 int ret;
1244
1245 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1246 &rte_flow_item_ipv4_mask,
1247 sizeof(struct rte_flow_item_ipv4), error);
1248 if (ret)
1249 return ret;
1250
1251 if (mask->hdr.sent_seq ||
1252 mask->hdr.recv_ack ||
1253 mask->hdr.data_off ||
1254 mask->hdr.tcp_flags ||
1255 mask->hdr.rx_win ||
1256 mask->hdr.cksum ||
1257 mask->hdr.tcp_urp) {
1258 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1259 NULL, "Not supported by classifier\n");
1260 return -rte_errno;
1261 }
1262
1263 if (mask->hdr.src_port) {
1264 MRVL_LOG(WARNING, "tcp sport mask is ignored");
1265 ret = mrvl_parse_tcp_sport(spec, mask, flow);
1266 if (ret)
1267 goto out;
1268 }
1269
1270 if (mask->hdr.dst_port) {
1271 MRVL_LOG(WARNING, "tcp dport mask is ignored");
1272 ret = mrvl_parse_tcp_dport(spec, mask, flow);
1273 if (ret)
1274 goto out;
1275 }
1276
1277 return 0;
1278out:
1279 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1280 "Reached maximum number of fields in cls tbl key\n");
1281 return -rte_errno;
1282}
1283
1284/**
1285 * Parse udp flow item.
1286 *
1287 * @param item Pointer to the flow item.
1288 * @param flow Pointer to the flow.
1289 * @param error Pointer to the flow error.
11fdf7f2
TL
1290 * @returns 0 on success, negative value otherwise.
1291 */
1292static int
1293mrvl_parse_udp(const struct rte_flow_item *item,
1294 struct rte_flow *flow,
1295 struct rte_flow_error *error)
1296{
1297 const struct rte_flow_item_udp *spec = NULL, *mask = NULL;
1298 int ret;
1299
1300 ret = mrvl_parse_init(item, (const void **)&spec, (const void **)&mask,
1301 &rte_flow_item_ipv4_mask,
1302 sizeof(struct rte_flow_item_ipv4), error);
1303 if (ret)
1304 return ret;
1305
1306 if (mask->hdr.dgram_len ||
1307 mask->hdr.dgram_cksum) {
1308 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM,
1309 NULL, "Not supported by classifier\n");
1310 return -rte_errno;
1311 }
1312
1313 if (mask->hdr.src_port) {
1314 MRVL_LOG(WARNING, "udp sport mask is ignored");
1315 ret = mrvl_parse_udp_sport(spec, mask, flow);
1316 if (ret)
1317 goto out;
1318 }
1319
1320 if (mask->hdr.dst_port) {
1321 MRVL_LOG(WARNING, "udp dport mask is ignored");
1322 ret = mrvl_parse_udp_dport(spec, mask, flow);
1323 if (ret)
1324 goto out;
1325 }
1326
1327 return 0;
1328out:
1329 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
1330 "Reached maximum number of fields in cls tbl key\n");
1331 return -rte_errno;
1332}
1333
1334/**
1335 * Parse flow pattern composed of the the eth item.
1336 *
1337 * @param pattern Pointer to the flow pattern table.
1338 * @param flow Pointer to the flow.
1339 * @param error Pointer to the flow error.
1340 * @returns 0 in case of success, negative value otherwise.
1341 */
1342static int
1343mrvl_parse_pattern_eth(const struct rte_flow_item pattern[],
1344 struct rte_flow *flow,
1345 struct rte_flow_error *error)
1346{
1347 return mrvl_parse_eth(pattern, flow, error);
1348}
1349
1350/**
1351 * Parse flow pattern composed of the eth and vlan items.
1352 *
1353 * @param pattern Pointer to the flow pattern table.
1354 * @param flow Pointer to the flow.
1355 * @param error Pointer to the flow error.
1356 * @returns 0 in case of success, negative value otherwise.
1357 */
1358static int
1359mrvl_parse_pattern_eth_vlan(const struct rte_flow_item pattern[],
1360 struct rte_flow *flow,
1361 struct rte_flow_error *error)
1362{
1363 const struct rte_flow_item *item = mrvl_next_item(pattern);
1364 int ret;
1365
1366 ret = mrvl_parse_eth(item, flow, error);
1367 if (ret)
1368 return ret;
1369
1370 item = mrvl_next_item(item + 1);
1371
1372 return mrvl_parse_vlan(item, flow, error);
1373}
1374
1375/**
1376 * Parse flow pattern composed of the eth, vlan and ip4/ip6 items.
1377 *
1378 * @param pattern Pointer to the flow pattern table.
1379 * @param flow Pointer to the flow.
1380 * @param error Pointer to the flow error.
1381 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1382 * @returns 0 in case of success, negative value otherwise.
1383 */
1384static int
1385mrvl_parse_pattern_eth_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1386 struct rte_flow *flow,
1387 struct rte_flow_error *error, int ip6)
1388{
1389 const struct rte_flow_item *item = mrvl_next_item(pattern);
1390 int ret;
1391
1392 ret = mrvl_parse_eth(item, flow, error);
1393 if (ret)
1394 return ret;
1395
1396 item = mrvl_next_item(item + 1);
1397 ret = mrvl_parse_vlan(item, flow, error);
1398 if (ret)
1399 return ret;
1400
1401 item = mrvl_next_item(item + 1);
1402
1403 return ip6 ? mrvl_parse_ip6(item, flow, error) :
1404 mrvl_parse_ip4(item, flow, error);
1405}
1406
1407/**
1408 * Parse flow pattern composed of the eth, vlan and ipv4 items.
1409 *
1410 * @param pattern Pointer to the flow pattern table.
1411 * @param flow Pointer to the flow.
1412 * @param error Pointer to the flow error.
1413 * @returns 0 in case of success, negative value otherwise.
1414 */
1415static int
1416mrvl_parse_pattern_eth_vlan_ip4(const struct rte_flow_item pattern[],
1417 struct rte_flow *flow,
1418 struct rte_flow_error *error)
1419{
1420 return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 0);
1421}
1422
1423/**
1424 * Parse flow pattern composed of the eth, vlan and ipv6 items.
1425 *
1426 * @param pattern Pointer to the flow pattern table.
1427 * @param flow Pointer to the flow.
1428 * @param error Pointer to the flow error.
1429 * @returns 0 in case of success, negative value otherwise.
1430 */
1431static int
1432mrvl_parse_pattern_eth_vlan_ip6(const struct rte_flow_item pattern[],
1433 struct rte_flow *flow,
1434 struct rte_flow_error *error)
1435{
1436 return mrvl_parse_pattern_eth_vlan_ip4_ip6(pattern, flow, error, 1);
1437}
1438
1439/**
1440 * Parse flow pattern composed of the eth and ip4/ip6 items.
1441 *
1442 * @param pattern Pointer to the flow pattern table.
1443 * @param flow Pointer to the flow.
1444 * @param error Pointer to the flow error.
1445 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1446 * @returns 0 in case of success, negative value otherwise.
1447 */
1448static int
1449mrvl_parse_pattern_eth_ip4_ip6(const struct rte_flow_item pattern[],
1450 struct rte_flow *flow,
1451 struct rte_flow_error *error, int ip6)
1452{
1453 const struct rte_flow_item *item = mrvl_next_item(pattern);
1454 int ret;
1455
1456 ret = mrvl_parse_eth(item, flow, error);
1457 if (ret)
1458 return ret;
1459
1460 item = mrvl_next_item(item + 1);
1461
1462 return ip6 ? mrvl_parse_ip6(item, flow, error) :
1463 mrvl_parse_ip4(item, flow, error);
1464}
1465
1466/**
1467 * Parse flow pattern composed of the eth and ipv4 items.
1468 *
1469 * @param pattern Pointer to the flow pattern table.
1470 * @param flow Pointer to the flow.
1471 * @param error Pointer to the flow error.
1472 * @returns 0 in case of success, negative value otherwise.
1473 */
1474static inline int
1475mrvl_parse_pattern_eth_ip4(const struct rte_flow_item pattern[],
1476 struct rte_flow *flow,
1477 struct rte_flow_error *error)
1478{
1479 return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1480}
1481
1482/**
1483 * Parse flow pattern composed of the eth and ipv6 items.
1484 *
1485 * @param pattern Pointer to the flow pattern table.
1486 * @param flow Pointer to the flow.
1487 * @param error Pointer to the flow error.
1488 * @returns 0 in case of success, negative value otherwise.
1489 */
1490static inline int
1491mrvl_parse_pattern_eth_ip6(const struct rte_flow_item pattern[],
1492 struct rte_flow *flow,
1493 struct rte_flow_error *error)
1494{
1495 return mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1496}
1497
1498/**
1499 * Parse flow pattern composed of the eth, ip4 and tcp/udp items.
1500 *
1501 * @param pattern Pointer to the flow pattern table.
1502 * @param flow Pointer to the flow.
1503 * @param error Pointer to the flow error.
1504 * @param tcp 1 to parse tcp item, 0 to parse udp item.
1505 * @returns 0 in case of success, negative value otherwise.
1506 */
1507static int
1508mrvl_parse_pattern_eth_ip4_tcp_udp(const struct rte_flow_item pattern[],
1509 struct rte_flow *flow,
1510 struct rte_flow_error *error, int tcp)
1511{
1512 const struct rte_flow_item *item = mrvl_next_item(pattern);
1513 int ret;
1514
1515 ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 0);
1516 if (ret)
1517 return ret;
1518
1519 item = mrvl_next_item(item + 1);
1520 item = mrvl_next_item(item + 1);
1521
1522 if (tcp)
1523 return mrvl_parse_tcp(item, flow, error);
1524
1525 return mrvl_parse_udp(item, flow, error);
1526}
1527
1528/**
1529 * Parse flow pattern composed of the eth, ipv4 and tcp items.
1530 *
1531 * @param pattern Pointer to the flow pattern table.
1532 * @param flow Pointer to the flow.
1533 * @param error Pointer to the flow error.
1534 * @returns 0 in case of success, negative value otherwise.
1535 */
1536static inline int
1537mrvl_parse_pattern_eth_ip4_tcp(const struct rte_flow_item pattern[],
1538 struct rte_flow *flow,
1539 struct rte_flow_error *error)
1540{
1541 return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 1);
1542}
1543
1544/**
1545 * Parse flow pattern composed of the eth, ipv4 and udp items.
1546 *
1547 * @param pattern Pointer to the flow pattern table.
1548 * @param flow Pointer to the flow.
1549 * @param error Pointer to the flow error.
1550 * @returns 0 in case of success, negative value otherwise.
1551 */
1552static inline int
1553mrvl_parse_pattern_eth_ip4_udp(const struct rte_flow_item pattern[],
1554 struct rte_flow *flow,
1555 struct rte_flow_error *error)
1556{
1557 return mrvl_parse_pattern_eth_ip4_tcp_udp(pattern, flow, error, 0);
1558}
1559
1560/**
1561 * Parse flow pattern composed of the eth, ipv6 and tcp/udp items.
1562 *
1563 * @param pattern Pointer to the flow pattern table.
1564 * @param flow Pointer to the flow.
1565 * @param error Pointer to the flow error.
1566 * @param tcp 1 to parse tcp item, 0 to parse udp item.
1567 * @returns 0 in case of success, negative value otherwise.
1568 */
1569static int
1570mrvl_parse_pattern_eth_ip6_tcp_udp(const struct rte_flow_item pattern[],
1571 struct rte_flow *flow,
1572 struct rte_flow_error *error, int tcp)
1573{
1574 const struct rte_flow_item *item = mrvl_next_item(pattern);
1575 int ret;
1576
1577 ret = mrvl_parse_pattern_eth_ip4_ip6(pattern, flow, error, 1);
1578 if (ret)
1579 return ret;
1580
1581 item = mrvl_next_item(item + 1);
1582 item = mrvl_next_item(item + 1);
1583
1584 if (tcp)
1585 return mrvl_parse_tcp(item, flow, error);
1586
1587 return mrvl_parse_udp(item, flow, error);
1588}
1589
1590/**
1591 * Parse flow pattern composed of the eth, ipv6 and tcp items.
1592 *
1593 * @param pattern Pointer to the flow pattern table.
1594 * @param flow Pointer to the flow.
1595 * @param error Pointer to the flow error.
1596 * @returns 0 in case of success, negative value otherwise.
1597 */
1598static inline int
1599mrvl_parse_pattern_eth_ip6_tcp(const struct rte_flow_item pattern[],
1600 struct rte_flow *flow,
1601 struct rte_flow_error *error)
1602{
1603 return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 1);
1604}
1605
1606/**
1607 * Parse flow pattern composed of the eth, ipv6 and udp items.
1608 *
1609 * @param pattern Pointer to the flow pattern table.
1610 * @param flow Pointer to the flow.
1611 * @param error Pointer to the flow error.
1612 * @returns 0 in case of success, negative value otherwise.
1613 */
1614static inline int
1615mrvl_parse_pattern_eth_ip6_udp(const struct rte_flow_item pattern[],
1616 struct rte_flow *flow,
1617 struct rte_flow_error *error)
1618{
1619 return mrvl_parse_pattern_eth_ip6_tcp_udp(pattern, flow, error, 0);
1620}
1621
1622/**
1623 * Parse flow pattern composed of the vlan item.
1624 *
1625 * @param pattern Pointer to the flow pattern table.
1626 * @param flow Pointer to the flow.
1627 * @param error Pointer to the flow error.
1628 * @returns 0 in case of success, negative value otherwise.
1629 */
1630static int
1631mrvl_parse_pattern_vlan(const struct rte_flow_item pattern[],
1632 struct rte_flow *flow,
1633 struct rte_flow_error *error)
1634{
1635 const struct rte_flow_item *item = mrvl_next_item(pattern);
1636
1637 return mrvl_parse_vlan(item, flow, error);
1638}
1639
1640/**
1641 * Parse flow pattern composed of the vlan and ip4/ip6 items.
1642 *
1643 * @param pattern Pointer to the flow pattern table.
1644 * @param flow Pointer to the flow.
1645 * @param error Pointer to the flow error.
1646 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1647 * @returns 0 in case of success, negative value otherwise.
1648 */
1649static int
1650mrvl_parse_pattern_vlan_ip4_ip6(const struct rte_flow_item pattern[],
1651 struct rte_flow *flow,
1652 struct rte_flow_error *error, int ip6)
1653{
1654 const struct rte_flow_item *item = mrvl_next_item(pattern);
1655 int ret;
1656
1657 ret = mrvl_parse_vlan(item, flow, error);
1658 if (ret)
1659 return ret;
1660
1661 item = mrvl_next_item(item + 1);
1662
1663 return ip6 ? mrvl_parse_ip6(item, flow, error) :
1664 mrvl_parse_ip4(item, flow, error);
1665}
1666
1667/**
1668 * Parse flow pattern composed of the vlan and ipv4 items.
1669 *
1670 * @param pattern Pointer to the flow pattern table.
1671 * @param flow Pointer to the flow.
1672 * @param error Pointer to the flow error.
1673 * @returns 0 in case of success, negative value otherwise.
1674 */
1675static inline int
1676mrvl_parse_pattern_vlan_ip4(const struct rte_flow_item pattern[],
1677 struct rte_flow *flow,
1678 struct rte_flow_error *error)
1679{
1680 return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1681}
1682
1683/**
1684 * Parse flow pattern composed of the vlan, ipv4 and tcp/udp items.
1685 *
1686 * @param pattern Pointer to the flow pattern table.
1687 * @param flow Pointer to the flow.
1688 * @param error Pointer to the flow error.
1689 * @returns 0 in case of success, negative value otherwise.
1690 */
1691static int
1692mrvl_parse_pattern_vlan_ip_tcp_udp(const struct rte_flow_item pattern[],
1693 struct rte_flow *flow,
1694 struct rte_flow_error *error, int tcp)
1695{
1696 const struct rte_flow_item *item = mrvl_next_item(pattern);
1697 int ret;
1698
1699 ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 0);
1700 if (ret)
1701 return ret;
1702
1703 item = mrvl_next_item(item + 1);
1704 item = mrvl_next_item(item + 1);
1705
1706 if (tcp)
1707 return mrvl_parse_tcp(item, flow, error);
1708
1709 return mrvl_parse_udp(item, flow, error);
1710}
1711
1712/**
1713 * Parse flow pattern composed of the vlan, ipv4 and tcp items.
1714 *
1715 * @param pattern Pointer to the flow pattern table.
1716 * @param flow Pointer to the flow.
1717 * @param error Pointer to the flow error.
1718 * @returns 0 in case of success, negative value otherwise.
1719 */
1720static inline int
1721mrvl_parse_pattern_vlan_ip_tcp(const struct rte_flow_item pattern[],
1722 struct rte_flow *flow,
1723 struct rte_flow_error *error)
1724{
1725 return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 1);
1726}
1727
1728/**
1729 * Parse flow pattern composed of the vlan, ipv4 and udp items.
1730 *
1731 * @param pattern Pointer to the flow pattern table.
1732 * @param flow Pointer to the flow.
1733 * @param error Pointer to the flow error.
1734 * @returns 0 in case of success, negative value otherwise.
1735 */
1736static inline int
1737mrvl_parse_pattern_vlan_ip_udp(const struct rte_flow_item pattern[],
1738 struct rte_flow *flow,
1739 struct rte_flow_error *error)
1740{
1741 return mrvl_parse_pattern_vlan_ip_tcp_udp(pattern, flow, error, 0);
1742}
1743
1744/**
1745 * Parse flow pattern composed of the vlan and ipv6 items.
1746 *
1747 * @param pattern Pointer to the flow pattern table.
1748 * @param flow Pointer to the flow.
1749 * @param error Pointer to the flow error.
1750 * @returns 0 in case of success, negative value otherwise.
1751 */
1752static inline int
1753mrvl_parse_pattern_vlan_ip6(const struct rte_flow_item pattern[],
1754 struct rte_flow *flow,
1755 struct rte_flow_error *error)
1756{
1757 return mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1758}
1759
1760/**
1761 * Parse flow pattern composed of the vlan, ipv6 and tcp/udp items.
1762 *
1763 * @param pattern Pointer to the flow pattern table.
1764 * @param flow Pointer to the flow.
1765 * @param error Pointer to the flow error.
1766 * @returns 0 in case of success, negative value otherwise.
1767 */
1768static int
1769mrvl_parse_pattern_vlan_ip6_tcp_udp(const struct rte_flow_item pattern[],
1770 struct rte_flow *flow,
1771 struct rte_flow_error *error, int tcp)
1772{
1773 const struct rte_flow_item *item = mrvl_next_item(pattern);
1774 int ret;
1775
1776 ret = mrvl_parse_pattern_vlan_ip4_ip6(pattern, flow, error, 1);
1777 if (ret)
1778 return ret;
1779
1780 item = mrvl_next_item(item + 1);
1781 item = mrvl_next_item(item + 1);
1782
1783 if (tcp)
1784 return mrvl_parse_tcp(item, flow, error);
1785
1786 return mrvl_parse_udp(item, flow, error);
1787}
1788
1789/**
1790 * Parse flow pattern composed of the vlan, ipv6 and tcp items.
1791 *
1792 * @param pattern Pointer to the flow pattern table.
1793 * @param flow Pointer to the flow.
1794 * @param error Pointer to the flow error.
1795 * @returns 0 in case of success, negative value otherwise.
1796 */
1797static inline int
1798mrvl_parse_pattern_vlan_ip6_tcp(const struct rte_flow_item pattern[],
1799 struct rte_flow *flow,
1800 struct rte_flow_error *error)
1801{
1802 return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 1);
1803}
1804
1805/**
1806 * Parse flow pattern composed of the vlan, ipv6 and udp items.
1807 *
1808 * @param pattern Pointer to the flow pattern table.
1809 * @param flow Pointer to the flow.
1810 * @param error Pointer to the flow error.
1811 * @returns 0 in case of success, negative value otherwise.
1812 */
1813static inline int
1814mrvl_parse_pattern_vlan_ip6_udp(const struct rte_flow_item pattern[],
1815 struct rte_flow *flow,
1816 struct rte_flow_error *error)
1817{
1818 return mrvl_parse_pattern_vlan_ip6_tcp_udp(pattern, flow, error, 0);
1819}
1820
1821/**
1822 * Parse flow pattern composed of the ip4/ip6 item.
1823 *
1824 * @param pattern Pointer to the flow pattern table.
1825 * @param flow Pointer to the flow.
1826 * @param error Pointer to the flow error.
1827 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1828 * @returns 0 in case of success, negative value otherwise.
1829 */
1830static int
1831mrvl_parse_pattern_ip4_ip6(const struct rte_flow_item pattern[],
1832 struct rte_flow *flow,
1833 struct rte_flow_error *error, int ip6)
1834{
1835 const struct rte_flow_item *item = mrvl_next_item(pattern);
1836
1837 return ip6 ? mrvl_parse_ip6(item, flow, error) :
1838 mrvl_parse_ip4(item, flow, error);
1839}
1840
1841/**
1842 * Parse flow pattern composed of the ipv4 item.
1843 *
1844 * @param pattern Pointer to the flow pattern table.
1845 * @param flow Pointer to the flow.
1846 * @param error Pointer to the flow error.
1847 * @returns 0 in case of success, negative value otherwise.
1848 */
1849static inline int
1850mrvl_parse_pattern_ip4(const struct rte_flow_item pattern[],
1851 struct rte_flow *flow,
1852 struct rte_flow_error *error)
1853{
1854 return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 0);
1855}
1856
1857/**
1858 * Parse flow pattern composed of the ipv6 item.
1859 *
1860 * @param pattern Pointer to the flow pattern table.
1861 * @param flow Pointer to the flow.
1862 * @param error Pointer to the flow error.
1863 * @returns 0 in case of success, negative value otherwise.
1864 */
1865static inline int
1866mrvl_parse_pattern_ip6(const struct rte_flow_item pattern[],
1867 struct rte_flow *flow,
1868 struct rte_flow_error *error)
1869{
1870 return mrvl_parse_pattern_ip4_ip6(pattern, flow, error, 1);
1871}
1872
1873/**
1874 * Parse flow pattern composed of the ip4/ip6 and tcp items.
1875 *
1876 * @param pattern Pointer to the flow pattern table.
1877 * @param flow Pointer to the flow.
1878 * @param error Pointer to the flow error.
1879 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
1880 * @returns 0 in case of success, negative value otherwise.
1881 */
1882static int
1883mrvl_parse_pattern_ip4_ip6_tcp(const struct rte_flow_item pattern[],
1884 struct rte_flow *flow,
1885 struct rte_flow_error *error, int ip6)
1886{
1887 const struct rte_flow_item *item = mrvl_next_item(pattern);
1888 int ret;
1889
1890 ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1891 mrvl_parse_ip4(item, flow, error);
1892 if (ret)
1893 return ret;
1894
1895 item = mrvl_next_item(item + 1);
1896
1897 return mrvl_parse_tcp(item, flow, error);
1898}
1899
1900/**
1901 * Parse flow pattern composed of the ipv4 and tcp items.
1902 *
1903 * @param pattern Pointer to the flow pattern table.
1904 * @param flow Pointer to the flow.
1905 * @param error Pointer to the flow error.
1906 * @returns 0 in case of success, negative value otherwise.
1907 */
1908static inline int
1909mrvl_parse_pattern_ip4_tcp(const struct rte_flow_item pattern[],
1910 struct rte_flow *flow,
1911 struct rte_flow_error *error)
1912{
1913 return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 0);
1914}
1915
1916/**
1917 * Parse flow pattern composed of the ipv6 and tcp items.
1918 *
1919 * @param pattern Pointer to the flow pattern table.
1920 * @param flow Pointer to the flow.
1921 * @param error Pointer to the flow error.
1922 * @returns 0 in case of success, negative value otherwise.
1923 */
1924static inline int
1925mrvl_parse_pattern_ip6_tcp(const struct rte_flow_item pattern[],
1926 struct rte_flow *flow,
1927 struct rte_flow_error *error)
1928{
1929 return mrvl_parse_pattern_ip4_ip6_tcp(pattern, flow, error, 1);
1930}
1931
1932/**
1933 * Parse flow pattern composed of the ipv4/ipv6 and udp items.
1934 *
1935 * @param pattern Pointer to the flow pattern table.
1936 * @param flow Pointer to the flow.
1937 * @param error Pointer to the flow error.
9f95a23c 1938 * @param ip6 1 to parse ip6 item, 0 to parse ip4 item.
11fdf7f2
TL
1939 * @returns 0 in case of success, negative value otherwise.
1940 */
1941static int
1942mrvl_parse_pattern_ip4_ip6_udp(const struct rte_flow_item pattern[],
1943 struct rte_flow *flow,
1944 struct rte_flow_error *error, int ip6)
1945{
1946 const struct rte_flow_item *item = mrvl_next_item(pattern);
1947 int ret;
1948
1949 ret = ip6 ? mrvl_parse_ip6(item, flow, error) :
1950 mrvl_parse_ip4(item, flow, error);
1951 if (ret)
1952 return ret;
1953
1954 item = mrvl_next_item(item + 1);
1955
1956 return mrvl_parse_udp(item, flow, error);
1957}
1958
1959/**
1960 * Parse flow pattern composed of the ipv4 and udp items.
1961 *
1962 * @param pattern Pointer to the flow pattern table.
1963 * @param flow Pointer to the flow.
1964 * @param error Pointer to the flow error.
1965 * @returns 0 in case of success, negative value otherwise.
1966 */
1967static inline int
1968mrvl_parse_pattern_ip4_udp(const struct rte_flow_item pattern[],
1969 struct rte_flow *flow,
1970 struct rte_flow_error *error)
1971{
1972 return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 0);
1973}
1974
1975/**
1976 * Parse flow pattern composed of the ipv6 and udp items.
1977 *
1978 * @param pattern Pointer to the flow pattern table.
1979 * @param flow Pointer to the flow.
1980 * @param error Pointer to the flow error.
1981 * @returns 0 in case of success, negative value otherwise.
1982 */
1983static inline int
1984mrvl_parse_pattern_ip6_udp(const struct rte_flow_item pattern[],
1985 struct rte_flow *flow,
1986 struct rte_flow_error *error)
1987{
1988 return mrvl_parse_pattern_ip4_ip6_udp(pattern, flow, error, 1);
1989}
1990
1991/**
1992 * Parse flow pattern composed of the tcp item.
1993 *
1994 * @param pattern Pointer to the flow pattern table.
1995 * @param flow Pointer to the flow.
1996 * @param error Pointer to the flow error.
1997 * @returns 0 in case of success, negative value otherwise.
1998 */
1999static int
2000mrvl_parse_pattern_tcp(const struct rte_flow_item pattern[],
2001 struct rte_flow *flow,
2002 struct rte_flow_error *error)
2003{
2004 const struct rte_flow_item *item = mrvl_next_item(pattern);
2005
2006 return mrvl_parse_tcp(item, flow, error);
2007}
2008
2009/**
2010 * Parse flow pattern composed of the udp item.
2011 *
2012 * @param pattern Pointer to the flow pattern table.
2013 * @param flow Pointer to the flow.
2014 * @param error Pointer to the flow error.
2015 * @returns 0 in case of success, negative value otherwise.
2016 */
2017static int
2018mrvl_parse_pattern_udp(const struct rte_flow_item pattern[],
2019 struct rte_flow *flow,
2020 struct rte_flow_error *error)
2021{
2022 const struct rte_flow_item *item = mrvl_next_item(pattern);
2023
2024 return mrvl_parse_udp(item, flow, error);
2025}
2026
2027/**
2028 * Structure used to map specific flow pattern to the pattern parse callback
2029 * which will iterate over each pattern item and extract relevant data.
2030 */
2031static const struct {
2032 const enum rte_flow_item_type *pattern;
2033 int (*parse)(const struct rte_flow_item pattern[],
2034 struct rte_flow *flow,
2035 struct rte_flow_error *error);
2036} mrvl_patterns[] = {
2037 { pattern_eth, mrvl_parse_pattern_eth },
2038 { pattern_eth_vlan, mrvl_parse_pattern_eth_vlan },
2039 { pattern_eth_vlan_ip, mrvl_parse_pattern_eth_vlan_ip4 },
2040 { pattern_eth_vlan_ip6, mrvl_parse_pattern_eth_vlan_ip6 },
2041 { pattern_eth_ip4, mrvl_parse_pattern_eth_ip4 },
2042 { pattern_eth_ip4_tcp, mrvl_parse_pattern_eth_ip4_tcp },
2043 { pattern_eth_ip4_udp, mrvl_parse_pattern_eth_ip4_udp },
2044 { pattern_eth_ip6, mrvl_parse_pattern_eth_ip6 },
2045 { pattern_eth_ip6_tcp, mrvl_parse_pattern_eth_ip6_tcp },
2046 { pattern_eth_ip6_udp, mrvl_parse_pattern_eth_ip6_udp },
2047 { pattern_vlan, mrvl_parse_pattern_vlan },
2048 { pattern_vlan_ip, mrvl_parse_pattern_vlan_ip4 },
2049 { pattern_vlan_ip_tcp, mrvl_parse_pattern_vlan_ip_tcp },
2050 { pattern_vlan_ip_udp, mrvl_parse_pattern_vlan_ip_udp },
2051 { pattern_vlan_ip6, mrvl_parse_pattern_vlan_ip6 },
2052 { pattern_vlan_ip6_tcp, mrvl_parse_pattern_vlan_ip6_tcp },
2053 { pattern_vlan_ip6_udp, mrvl_parse_pattern_vlan_ip6_udp },
2054 { pattern_ip, mrvl_parse_pattern_ip4 },
2055 { pattern_ip_tcp, mrvl_parse_pattern_ip4_tcp },
2056 { pattern_ip_udp, mrvl_parse_pattern_ip4_udp },
2057 { pattern_ip6, mrvl_parse_pattern_ip6 },
2058 { pattern_ip6_tcp, mrvl_parse_pattern_ip6_tcp },
2059 { pattern_ip6_udp, mrvl_parse_pattern_ip6_udp },
2060 { pattern_tcp, mrvl_parse_pattern_tcp },
2061 { pattern_udp, mrvl_parse_pattern_udp }
2062};
2063
2064/**
2065 * Check whether provided pattern matches any of the supported ones.
2066 *
2067 * @param type_pattern Pointer to the pattern type.
2068 * @param item_pattern Pointer to the flow pattern.
2069 * @returns 1 in case of success, 0 value otherwise.
2070 */
2071static int
2072mrvl_patterns_match(const enum rte_flow_item_type *type_pattern,
2073 const struct rte_flow_item *item_pattern)
2074{
2075 const enum rte_flow_item_type *type = type_pattern;
2076 const struct rte_flow_item *item = item_pattern;
2077
2078 for (;;) {
2079 if (item->type == RTE_FLOW_ITEM_TYPE_VOID) {
2080 item++;
2081 continue;
2082 }
2083
2084 if (*type == RTE_FLOW_ITEM_TYPE_END ||
2085 item->type == RTE_FLOW_ITEM_TYPE_END)
2086 break;
2087
2088 if (*type != item->type)
2089 break;
2090
2091 item++;
2092 type++;
2093 }
2094
2095 return *type == item->type;
2096}
2097
2098/**
2099 * Parse flow attribute.
2100 *
2101 * This will check whether the provided attribute's flags are supported.
2102 *
2103 * @param priv Unused
2104 * @param attr Pointer to the flow attribute.
2105 * @param flow Unused
2106 * @param error Pointer to the flow error.
2107 * @returns 0 in case of success, negative value otherwise.
2108 */
2109static int
2110mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused,
2111 const struct rte_flow_attr *attr,
2112 struct rte_flow *flow __rte_unused,
2113 struct rte_flow_error *error)
2114{
2115 if (!attr) {
2116 rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR,
2117 NULL, "NULL attribute");
2118 return -rte_errno;
2119 }
2120
2121 if (attr->group) {
2122 rte_flow_error_set(error, ENOTSUP,
2123 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, NULL,
2124 "Groups are not supported");
2125 return -rte_errno;
2126 }
2127 if (attr->priority) {
2128 rte_flow_error_set(error, ENOTSUP,
2129 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, NULL,
2130 "Priorities are not supported");
2131 return -rte_errno;
2132 }
2133 if (!attr->ingress) {
2134 rte_flow_error_set(error, ENOTSUP,
2135 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, NULL,
2136 "Only ingress is supported");
2137 return -rte_errno;
2138 }
2139 if (attr->egress) {
2140 rte_flow_error_set(error, ENOTSUP,
2141 RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
2142 "Egress is not supported");
2143 return -rte_errno;
2144 }
2145 if (attr->transfer) {
2146 rte_flow_error_set(error, ENOTSUP,
2147 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
2148 "Transfer is not supported");
2149 return -rte_errno;
2150 }
2151
2152 return 0;
2153}
2154
2155/**
2156 * Parse flow pattern.
2157 *
2158 * Specific classifier rule will be created as well.
2159 *
2160 * @param priv Unused
2161 * @param pattern Pointer to the flow pattern.
2162 * @param flow Pointer to the flow.
2163 * @param error Pointer to the flow error.
2164 * @returns 0 in case of success, negative value otherwise.
2165 */
2166static int
2167mrvl_flow_parse_pattern(struct mrvl_priv *priv __rte_unused,
2168 const struct rte_flow_item pattern[],
2169 struct rte_flow *flow,
2170 struct rte_flow_error *error)
2171{
2172 unsigned int i;
2173 int ret;
2174
2175 for (i = 0; i < RTE_DIM(mrvl_patterns); i++) {
2176 if (!mrvl_patterns_match(mrvl_patterns[i].pattern, pattern))
2177 continue;
2178
2179 ret = mrvl_patterns[i].parse(pattern, flow, error);
2180 if (ret)
2181 mrvl_free_all_key_mask(&flow->rule);
2182
2183 return ret;
2184 }
2185
2186 rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, NULL,
2187 "Unsupported pattern");
2188
2189 return -rte_errno;
2190}
2191
2192/**
2193 * Parse flow actions.
2194 *
2195 * @param priv Pointer to the port's private data.
2196 * @param actions Pointer the action table.
2197 * @param flow Pointer to the flow.
2198 * @param error Pointer to the flow error.
2199 * @returns 0 in case of success, negative value otherwise.
2200 */
2201static int
2202mrvl_flow_parse_actions(struct mrvl_priv *priv,
2203 const struct rte_flow_action actions[],
2204 struct rte_flow *flow,
2205 struct rte_flow_error *error)
2206{
2207 const struct rte_flow_action *action = actions;
2208 int specified = 0;
2209
2210 for (; action->type != RTE_FLOW_ACTION_TYPE_END; action++) {
2211 if (action->type == RTE_FLOW_ACTION_TYPE_VOID)
2212 continue;
2213
2214 if (action->type == RTE_FLOW_ACTION_TYPE_DROP) {
2215 flow->cos.ppio = priv->ppio;
2216 flow->cos.tc = 0;
2217 flow->action.type = PP2_CLS_TBL_ACT_DROP;
2218 flow->action.cos = &flow->cos;
2219 specified++;
2220 } else if (action->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
2221 const struct rte_flow_action_queue *q =
2222 (const struct rte_flow_action_queue *)
2223 action->conf;
2224
2225 if (q->index > priv->nb_rx_queues) {
2226 rte_flow_error_set(error, EINVAL,
2227 RTE_FLOW_ERROR_TYPE_ACTION,
2228 NULL,
2229 "Queue index out of range");
2230 return -rte_errno;
2231 }
2232
2233 if (priv->rxq_map[q->index].tc == MRVL_UNKNOWN_TC) {
2234 /*
2235 * Unknown TC mapping, mapping will not have
2236 * a correct queue.
2237 */
2238 MRVL_LOG(ERR,
2239 "Unknown TC mapping for queue %hu eth%hhu",
2240 q->index, priv->ppio_id);
2241
2242 rte_flow_error_set(error, EFAULT,
2243 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2244 NULL, NULL);
2245 return -rte_errno;
2246 }
2247
2248 MRVL_LOG(DEBUG,
2249 "Action: Assign packets to queue %d, tc:%d, q:%d",
2250 q->index, priv->rxq_map[q->index].tc,
2251 priv->rxq_map[q->index].inq);
2252
2253 flow->cos.ppio = priv->ppio;
2254 flow->cos.tc = priv->rxq_map[q->index].tc;
2255 flow->action.type = PP2_CLS_TBL_ACT_DONE;
2256 flow->action.cos = &flow->cos;
2257 specified++;
9f95a23c
TL
2258 } else if (action->type == RTE_FLOW_ACTION_TYPE_METER) {
2259 const struct rte_flow_action_meter *meter;
2260 struct mrvl_mtr *mtr;
2261
2262 meter = action->conf;
2263 if (!meter)
2264 return -rte_flow_error_set(error, EINVAL,
2265 RTE_FLOW_ERROR_TYPE_ACTION,
2266 NULL, "Invalid meter\n");
2267
2268 LIST_FOREACH(mtr, &priv->mtrs, next)
2269 if (mtr->mtr_id == meter->mtr_id)
2270 break;
2271
2272 if (!mtr)
2273 return -rte_flow_error_set(error, EINVAL,
2274 RTE_FLOW_ERROR_TYPE_ACTION,
2275 NULL,
2276 "Meter id does not exist\n");
2277
2278 if (!mtr->shared && mtr->refcnt)
2279 return -rte_flow_error_set(error, EPERM,
2280 RTE_FLOW_ERROR_TYPE_ACTION,
2281 NULL,
2282 "Meter cannot be shared\n");
2283
2284 /*
2285 * In case cos has already been set
2286 * do not modify it.
2287 */
2288 if (!flow->cos.ppio) {
2289 flow->cos.ppio = priv->ppio;
2290 flow->cos.tc = 0;
2291 }
2292
2293 flow->action.type = PP2_CLS_TBL_ACT_DONE;
2294 flow->action.cos = &flow->cos;
2295 flow->action.plcr = mtr->enabled ? mtr->plcr : NULL;
2296 flow->mtr = mtr;
2297 mtr->refcnt++;
2298 specified++;
11fdf7f2
TL
2299 } else {
2300 rte_flow_error_set(error, ENOTSUP,
2301 RTE_FLOW_ERROR_TYPE_ACTION, NULL,
2302 "Action not supported");
2303 return -rte_errno;
2304 }
11fdf7f2
TL
2305 }
2306
2307 if (!specified) {
2308 rte_flow_error_set(error, EINVAL,
9f95a23c
TL
2309 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2310 "Action not specified");
11fdf7f2
TL
2311 return -rte_errno;
2312 }
2313
2314 return 0;
2315}
2316
2317/**
2318 * Parse flow attribute, pattern and actions.
2319 *
2320 * @param priv Pointer to the port's private data.
2321 * @param attr Pointer to the flow attribute.
2322 * @param pattern Pointer to the flow pattern.
2323 * @param actions Pointer to the flow actions.
2324 * @param flow Pointer to the flow.
2325 * @param error Pointer to the flow error.
2326 * @returns 0 on success, negative value otherwise.
2327 */
2328static int
2329mrvl_flow_parse(struct mrvl_priv *priv, const struct rte_flow_attr *attr,
2330 const struct rte_flow_item pattern[],
2331 const struct rte_flow_action actions[],
2332 struct rte_flow *flow,
2333 struct rte_flow_error *error)
2334{
2335 int ret;
2336
2337 ret = mrvl_flow_parse_attr(priv, attr, flow, error);
2338 if (ret)
2339 return ret;
2340
2341 ret = mrvl_flow_parse_pattern(priv, pattern, flow, error);
2342 if (ret)
2343 return ret;
2344
2345 return mrvl_flow_parse_actions(priv, actions, flow, error);
2346}
2347
9f95a23c
TL
2348/**
2349 * Get engine type for the given flow.
2350 *
2351 * @param field Pointer to the flow.
2352 * @returns The type of the engine.
2353 */
11fdf7f2
TL
2354static inline enum pp2_cls_tbl_type
2355mrvl_engine_type(const struct rte_flow *flow)
2356{
2357 int i, size = 0;
2358
2359 for (i = 0; i < flow->rule.num_fields; i++)
2360 size += flow->rule.fields[i].size;
2361
2362 /*
2363 * For maskable engine type the key size must be up to 8 bytes.
2364 * For keys with size bigger than 8 bytes, engine type must
2365 * be set to exact match.
2366 */
2367 if (size > 8)
2368 return PP2_CLS_TBL_EXACT_MATCH;
2369
2370 return PP2_CLS_TBL_MASKABLE;
2371}
2372
9f95a23c
TL
2373/**
2374 * Create classifier table.
2375 *
2376 * @param dev Pointer to the device.
2377 * @param flow Pointer to the very first flow.
2378 * @returns 0 in case of success, negative value otherwise.
2379 */
11fdf7f2
TL
2380static int
2381mrvl_create_cls_table(struct rte_eth_dev *dev, struct rte_flow *first_flow)
2382{
2383 struct mrvl_priv *priv = dev->data->dev_private;
2384 struct pp2_cls_tbl_key *key = &priv->cls_tbl_params.key;
2385 int ret;
2386
2387 if (priv->cls_tbl) {
2388 pp2_cls_tbl_deinit(priv->cls_tbl);
2389 priv->cls_tbl = NULL;
2390 }
2391
2392 memset(&priv->cls_tbl_params, 0, sizeof(priv->cls_tbl_params));
2393
2394 priv->cls_tbl_params.type = mrvl_engine_type(first_flow);
2395 MRVL_LOG(INFO, "Setting cls search engine type to %s",
2396 priv->cls_tbl_params.type == PP2_CLS_TBL_EXACT_MATCH ?
2397 "exact" : "maskable");
2398 priv->cls_tbl_params.max_num_rules = MRVL_CLS_MAX_NUM_RULES;
2399 priv->cls_tbl_params.default_act.type = PP2_CLS_TBL_ACT_DONE;
2400 priv->cls_tbl_params.default_act.cos = &first_flow->cos;
2401
2402 if (first_flow->pattern & F_DMAC) {
2403 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2404 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_DA;
2405 key->key_size += 6;
2406 key->num_fields += 1;
2407 }
2408
2409 if (first_flow->pattern & F_SMAC) {
2410 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2411 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_SA;
2412 key->key_size += 6;
2413 key->num_fields += 1;
2414 }
2415
2416 if (first_flow->pattern & F_TYPE) {
2417 key->proto_field[key->num_fields].proto = MV_NET_PROTO_ETH;
2418 key->proto_field[key->num_fields].field.eth = MV_NET_ETH_F_TYPE;
2419 key->key_size += 2;
2420 key->num_fields += 1;
2421 }
2422
2423 if (first_flow->pattern & F_VLAN_ID) {
2424 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2425 key->proto_field[key->num_fields].field.vlan = MV_NET_VLAN_F_ID;
2426 key->key_size += 2;
2427 key->num_fields += 1;
2428 }
2429
2430 if (first_flow->pattern & F_VLAN_PRI) {
2431 key->proto_field[key->num_fields].proto = MV_NET_PROTO_VLAN;
2432 key->proto_field[key->num_fields].field.vlan =
2433 MV_NET_VLAN_F_PRI;
2434 key->key_size += 1;
2435 key->num_fields += 1;
2436 }
2437
2438 if (first_flow->pattern & F_IP4_TOS) {
2439 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
9f95a23c
TL
2440 key->proto_field[key->num_fields].field.ipv4 =
2441 MV_NET_IP4_F_DSCP;
11fdf7f2
TL
2442 key->key_size += 1;
2443 key->num_fields += 1;
2444 }
2445
2446 if (first_flow->pattern & F_IP4_SIP) {
2447 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2448 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_SA;
2449 key->key_size += 4;
2450 key->num_fields += 1;
2451 }
2452
2453 if (first_flow->pattern & F_IP4_DIP) {
2454 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2455 key->proto_field[key->num_fields].field.ipv4 = MV_NET_IP4_F_DA;
2456 key->key_size += 4;
2457 key->num_fields += 1;
2458 }
2459
2460 if (first_flow->pattern & F_IP4_PROTO) {
2461 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP4;
2462 key->proto_field[key->num_fields].field.ipv4 =
2463 MV_NET_IP4_F_PROTO;
2464 key->key_size += 1;
2465 key->num_fields += 1;
2466 }
2467
2468 if (first_flow->pattern & F_IP6_SIP) {
2469 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2470 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_SA;
2471 key->key_size += 16;
2472 key->num_fields += 1;
2473 }
2474
2475 if (first_flow->pattern & F_IP6_DIP) {
2476 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2477 key->proto_field[key->num_fields].field.ipv6 = MV_NET_IP6_F_DA;
2478 key->key_size += 16;
2479 key->num_fields += 1;
2480 }
2481
2482 if (first_flow->pattern & F_IP6_FLOW) {
2483 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2484 key->proto_field[key->num_fields].field.ipv6 =
2485 MV_NET_IP6_F_FLOW;
2486 key->key_size += 3;
2487 key->num_fields += 1;
2488 }
2489
2490 if (first_flow->pattern & F_IP6_NEXT_HDR) {
2491 key->proto_field[key->num_fields].proto = MV_NET_PROTO_IP6;
2492 key->proto_field[key->num_fields].field.ipv6 =
2493 MV_NET_IP6_F_NEXT_HDR;
2494 key->key_size += 1;
2495 key->num_fields += 1;
2496 }
2497
2498 if (first_flow->pattern & F_TCP_SPORT) {
2499 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2500 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2501 key->key_size += 2;
2502 key->num_fields += 1;
2503 }
2504
2505 if (first_flow->pattern & F_TCP_DPORT) {
2506 key->proto_field[key->num_fields].proto = MV_NET_PROTO_TCP;
2507 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_DP;
2508 key->key_size += 2;
2509 key->num_fields += 1;
2510 }
2511
2512 if (first_flow->pattern & F_UDP_SPORT) {
2513 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2514 key->proto_field[key->num_fields].field.tcp = MV_NET_TCP_F_SP;
2515 key->key_size += 2;
2516 key->num_fields += 1;
2517 }
2518
2519 if (first_flow->pattern & F_UDP_DPORT) {
2520 key->proto_field[key->num_fields].proto = MV_NET_PROTO_UDP;
2521 key->proto_field[key->num_fields].field.udp = MV_NET_TCP_F_DP;
2522 key->key_size += 2;
2523 key->num_fields += 1;
2524 }
2525
2526 ret = pp2_cls_tbl_init(&priv->cls_tbl_params, &priv->cls_tbl);
2527 if (!ret)
2528 priv->cls_tbl_pattern = first_flow->pattern;
2529
2530 return ret;
2531}
2532
2533/**
2534 * Check whether new flow can be added to the table
2535 *
2536 * @param priv Pointer to the port's private data.
2537 * @param flow Pointer to the new flow.
2538 * @return 1 in case flow can be added, 0 otherwise.
2539 */
2540static inline int
2541mrvl_flow_can_be_added(struct mrvl_priv *priv, const struct rte_flow *flow)
2542{
2543 return flow->pattern == priv->cls_tbl_pattern &&
2544 mrvl_engine_type(flow) == priv->cls_tbl_params.type;
2545}
2546
2547/**
2548 * DPDK flow create callback called when flow is to be created.
2549 *
2550 * @param dev Pointer to the device.
2551 * @param attr Pointer to the flow attribute.
2552 * @param pattern Pointer to the flow pattern.
2553 * @param actions Pointer to the flow actions.
2554 * @param error Pointer to the flow error.
2555 * @returns Pointer to the created flow in case of success, NULL otherwise.
2556 */
2557static struct rte_flow *
2558mrvl_flow_create(struct rte_eth_dev *dev,
2559 const struct rte_flow_attr *attr,
2560 const struct rte_flow_item pattern[],
2561 const struct rte_flow_action actions[],
2562 struct rte_flow_error *error)
2563{
2564 struct mrvl_priv *priv = dev->data->dev_private;
2565 struct rte_flow *flow, *first;
2566 int ret;
2567
2568 if (!dev->data->dev_started) {
2569 rte_flow_error_set(error, EINVAL,
2570 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2571 "Port must be started first\n");
2572 return NULL;
2573 }
2574
2575 flow = rte_zmalloc_socket(NULL, sizeof(*flow), 0, rte_socket_id());
2576 if (!flow)
2577 return NULL;
2578
2579 ret = mrvl_flow_parse(priv, attr, pattern, actions, flow, error);
2580 if (ret)
2581 goto out;
2582
2583 /*
2584 * Four cases here:
2585 *
2586 * 1. In case table does not exist - create one.
2587 * 2. In case table exists, is empty and new flow cannot be added
2588 * recreate table.
2589 * 3. In case table is not empty and new flow matches table format
2590 * add it.
2591 * 4. Otherwise flow cannot be added.
2592 */
2593 first = LIST_FIRST(&priv->flows);
2594 if (!priv->cls_tbl) {
2595 ret = mrvl_create_cls_table(dev, flow);
2596 } else if (!first && !mrvl_flow_can_be_added(priv, flow)) {
2597 ret = mrvl_create_cls_table(dev, flow);
2598 } else if (mrvl_flow_can_be_added(priv, flow)) {
2599 ret = 0;
2600 } else {
2601 rte_flow_error_set(error, EINVAL,
2602 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2603 "Pattern does not match cls table format\n");
2604 goto out;
2605 }
2606
2607 if (ret) {
2608 rte_flow_error_set(error, EINVAL,
2609 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2610 "Failed to create cls table\n");
2611 goto out;
2612 }
2613
2614 ret = pp2_cls_tbl_add_rule(priv->cls_tbl, &flow->rule, &flow->action);
2615 if (ret) {
2616 rte_flow_error_set(error, EINVAL,
2617 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2618 "Failed to add rule\n");
2619 goto out;
2620 }
2621
2622 LIST_INSERT_HEAD(&priv->flows, flow, next);
2623
2624 return flow;
2625out:
2626 rte_free(flow);
2627 return NULL;
2628}
2629
2630/**
2631 * Remove classifier rule associated with given flow.
2632 *
2633 * @param priv Pointer to the port's private data.
2634 * @param flow Pointer to the flow.
2635 * @param error Pointer to the flow error.
2636 * @returns 0 in case of success, negative value otherwise.
2637 */
2638static int
2639mrvl_flow_remove(struct mrvl_priv *priv, struct rte_flow *flow,
2640 struct rte_flow_error *error)
2641{
2642 int ret;
2643
2644 if (!priv->cls_tbl) {
2645 rte_flow_error_set(error, EINVAL,
2646 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2647 "Classifier table not initialized");
2648 return -rte_errno;
2649 }
2650
2651 ret = pp2_cls_tbl_remove_rule(priv->cls_tbl, &flow->rule);
2652 if (ret) {
2653 rte_flow_error_set(error, EINVAL,
2654 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2655 "Failed to remove rule");
2656 return -rte_errno;
2657 }
2658
2659 mrvl_free_all_key_mask(&flow->rule);
2660
9f95a23c
TL
2661 if (flow->mtr) {
2662 flow->mtr->refcnt--;
2663 flow->mtr = NULL;
2664 }
2665
11fdf7f2
TL
2666 return 0;
2667}
2668
2669/**
2670 * DPDK flow destroy callback called when flow is to be removed.
2671 *
9f95a23c 2672 * @param dev Pointer to the device.
11fdf7f2
TL
2673 * @param flow Pointer to the flow.
2674 * @param error Pointer to the flow error.
2675 * @returns 0 in case of success, negative value otherwise.
2676 */
2677static int
2678mrvl_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow,
2679 struct rte_flow_error *error)
2680{
2681 struct mrvl_priv *priv = dev->data->dev_private;
2682 struct rte_flow *f;
2683 int ret;
2684
2685 LIST_FOREACH(f, &priv->flows, next) {
2686 if (f == flow)
2687 break;
2688 }
2689
2690 if (!flow) {
2691 rte_flow_error_set(error, EINVAL,
2692 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
2693 "Rule was not found");
2694 return -rte_errno;
2695 }
2696
2697 LIST_REMOVE(f, next);
2698
2699 ret = mrvl_flow_remove(priv, flow, error);
2700 if (ret)
2701 return ret;
2702
2703 rte_free(flow);
2704
2705 return 0;
2706}
2707
2708/**
2709 * DPDK flow callback called to verify given attribute, pattern and actions.
2710 *
2711 * @param dev Pointer to the device.
2712 * @param attr Pointer to the flow attribute.
2713 * @param pattern Pointer to the flow pattern.
2714 * @param actions Pointer to the flow actions.
2715 * @param error Pointer to the flow error.
2716 * @returns 0 on success, negative value otherwise.
2717 */
2718static int
2719mrvl_flow_validate(struct rte_eth_dev *dev,
2720 const struct rte_flow_attr *attr,
2721 const struct rte_flow_item pattern[],
2722 const struct rte_flow_action actions[],
2723 struct rte_flow_error *error)
2724{
2725 static struct rte_flow *flow;
2726
2727 flow = mrvl_flow_create(dev, attr, pattern, actions, error);
2728 if (!flow)
2729 return -rte_errno;
2730
2731 mrvl_flow_destroy(dev, flow, error);
2732
2733 return 0;
2734}
2735
2736/**
2737 * DPDK flow flush callback called when flows are to be flushed.
2738 *
2739 * @param dev Pointer to the device.
2740 * @param error Pointer to the flow error.
2741 * @returns 0 in case of success, negative value otherwise.
2742 */
2743static int
2744mrvl_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error)
2745{
2746 struct mrvl_priv *priv = dev->data->dev_private;
2747
2748 while (!LIST_EMPTY(&priv->flows)) {
2749 struct rte_flow *flow = LIST_FIRST(&priv->flows);
2750 int ret = mrvl_flow_remove(priv, flow, error);
2751 if (ret)
2752 return ret;
2753
2754 LIST_REMOVE(flow, next);
2755 rte_free(flow);
2756 }
2757
2758 return 0;
2759}
2760
2761/**
2762 * DPDK flow isolate callback called to isolate port.
2763 *
2764 * @param dev Pointer to the device.
2765 * @param enable Pass 0/1 to disable/enable port isolation.
2766 * @param error Pointer to the flow error.
2767 * @returns 0 in case of success, negative value otherwise.
2768 */
2769static int
2770mrvl_flow_isolate(struct rte_eth_dev *dev, int enable,
2771 struct rte_flow_error *error)
2772{
2773 struct mrvl_priv *priv = dev->data->dev_private;
2774
2775 if (dev->data->dev_started) {
2776 rte_flow_error_set(error, EBUSY,
2777 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
2778 NULL, "Port must be stopped first\n");
2779 return -rte_errno;
2780 }
2781
2782 priv->isolated = enable;
2783
2784 return 0;
2785}
2786
2787const struct rte_flow_ops mrvl_flow_ops = {
2788 .validate = mrvl_flow_validate,
2789 .create = mrvl_flow_create,
2790 .destroy = mrvl_flow_destroy,
2791 .flush = mrvl_flow_flush,
2792 .isolate = mrvl_flow_isolate
2793};
9f95a23c
TL
2794
2795/**
2796 * Initialize flow resources.
2797 *
2798 * @param dev Pointer to the device.
2799 */
2800void
2801mrvl_flow_init(struct rte_eth_dev *dev)
2802{
2803 struct mrvl_priv *priv = dev->data->dev_private;
2804
2805 LIST_INIT(&priv->flows);
2806}
2807
2808/**
2809 * Cleanup flow resources.
2810 *
2811 * @param dev Pointer to the device.
2812 */
2813void
2814mrvl_flow_deinit(struct rte_eth_dev *dev)
2815{
2816 struct mrvl_priv *priv = dev->data->dev_private;
2817
2818 mrvl_flow_flush(dev, NULL);
2819
2820 if (priv->cls_tbl) {
2821 pp2_cls_tbl_deinit(priv->cls_tbl);
2822 priv->cls_tbl = NULL;
2823 }
2824}