xref: /dpdk/drivers/net/mlx5/linux/mlx5_flow_os.c (revision 8f1d23ece06adff5eae9f1b4365bdbbd3abee2b2)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 Mellanox Technologies, Ltd
3  */
4 
5 #include "mlx5_flow_os.h"
6 
7 #include <rte_thread.h>
8 
9 /* Key of thread specific flow workspace data. */
10 static rte_thread_key key_workspace;
11 
12 int
13 mlx5_flow_os_validate_item_esp(const struct rte_flow_item *item,
14 			    uint64_t item_flags,
15 			    uint8_t target_protocol,
16 			    struct rte_flow_error *error)
17 {
18 	const struct rte_flow_item_esp *mask = item->mask;
19 	const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
20 	const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3 :
21 				      MLX5_FLOW_LAYER_OUTER_L3;
22 	const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 :
23 				      MLX5_FLOW_LAYER_OUTER_L4;
24 	int ret;
25 
26 	if (!(item_flags & l3m))
27 		return rte_flow_error_set(error, EINVAL,
28 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
29 					  "L3 is mandatory to filter on L4");
30 	if (item_flags & l4m)
31 		return rte_flow_error_set(error, EINVAL,
32 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
33 					  "multiple L4 layers not supported");
34 	if (target_protocol != 0xff && target_protocol != IPPROTO_ESP)
35 		return rte_flow_error_set(error, EINVAL,
36 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
37 					  "protocol filtering not compatible"
38 					  " with ESP layer");
39 	if (!mask)
40 		mask = &rte_flow_item_esp_mask;
41 	ret = mlx5_flow_item_acceptable
42 		(item, (const uint8_t *)mask,
43 		 (const uint8_t *)&rte_flow_item_esp_mask,
44 		 sizeof(struct rte_flow_item_esp), MLX5_ITEM_RANGE_NOT_ACCEPTED,
45 		 error);
46 	if (ret < 0)
47 		return ret;
48 	return 0;
49 }
50 
51 int
52 mlx5_flow_os_init_workspace_once(void)
53 {
54 	if (rte_thread_key_create(&key_workspace, flow_release_workspace)) {
55 		DRV_LOG(ERR, "Can't create flow workspace data thread key.");
56 		rte_errno = ENOMEM;
57 		return -rte_errno;
58 	}
59 	return 0;
60 }
61 
62 void *
63 mlx5_flow_os_get_specific_workspace(void)
64 {
65 	return rte_thread_value_get(key_workspace);
66 }
67 
68 int
69 mlx5_flow_os_set_specific_workspace(struct mlx5_flow_workspace *data)
70 {
71 	return rte_thread_value_set(key_workspace, data);
72 }
73 
74 void
75 mlx5_flow_os_release_workspace(void)
76 {
77 	rte_thread_key_delete(key_workspace);
78 }
79