Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 Intel Corporation
3 : : */
4 : :
5 : : #include <sys/queue.h>
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <unistd.h>
11 : : #include <stdarg.h>
12 : :
13 : : #include <rte_ether.h>
14 : : #include <ethdev_driver.h>
15 : : #include <rte_malloc.h>
16 : : #include <rte_tailq.h>
17 : :
18 : : #include "iavf.h"
19 : : #include "iavf_generic_flow.h"
20 : : #include "../common/flow_check.h"
21 : : #include "virtchnl.h"
22 : : #include "iavf_rxtx.h"
23 : :
24 : : #define IAVF_FDIR_MAX_QREGION_SIZE 128
25 : :
26 : : #define IAVF_FDIR_IPV6_TC_OFFSET 20
27 : : #define IAVF_IPV6_TC_MASK (0xFF << IAVF_FDIR_IPV6_TC_OFFSET)
28 : :
29 : : #define IAVF_GTPU_EH_DWLINK 0
30 : : #define IAVF_GTPU_EH_UPLINK 1
31 : :
32 : : #define IAVF_FDIR_INSET_ETH (\
33 : : IAVF_INSET_DMAC | IAVF_INSET_SMAC | IAVF_INSET_ETHERTYPE)
34 : :
35 : : #define IAVF_FDIR_INSET_ETH_IPV4 (\
36 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
37 : : IAVF_INSET_IPV4_PROTO | IAVF_INSET_IPV4_TOS | \
38 : : IAVF_INSET_IPV4_TTL | IAVF_INSET_IPV4_ID)
39 : :
40 : : #define IAVF_FDIR_INSET_ETH_IPV4_UDP (\
41 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
42 : : IAVF_INSET_IPV4_TOS | IAVF_INSET_IPV4_TTL | \
43 : : IAVF_INSET_UDP_SRC_PORT | IAVF_INSET_UDP_DST_PORT)
44 : :
45 : : #define IAVF_FDIR_INSET_ETH_IPV4_TCP (\
46 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
47 : : IAVF_INSET_IPV4_TOS | IAVF_INSET_IPV4_TTL | \
48 : : IAVF_INSET_TCP_SRC_PORT | IAVF_INSET_TCP_DST_PORT)
49 : :
50 : : #define IAVF_FDIR_INSET_ETH_IPV4_SCTP (\
51 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
52 : : IAVF_INSET_IPV4_TOS | IAVF_INSET_IPV4_TTL | \
53 : : IAVF_INSET_SCTP_SRC_PORT | IAVF_INSET_SCTP_DST_PORT)
54 : :
55 : : #define IAVF_FDIR_INSET_ETH_IPV6 (\
56 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
57 : : IAVF_INSET_IPV6_NEXT_HDR | IAVF_INSET_IPV6_TC | \
58 : : IAVF_INSET_IPV6_HOP_LIMIT)
59 : :
60 : : #define IAVF_FDIR_INSET_ETH_IPV6_FRAG_EXT (\
61 : : IAVF_FDIR_INSET_ETH_IPV6 | IAVF_INSET_IPV6_ID)
62 : :
63 : : #define IAVF_FDIR_INSET_ETH_IPV6_UDP (\
64 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
65 : : IAVF_INSET_IPV6_TC | IAVF_INSET_IPV6_HOP_LIMIT | \
66 : : IAVF_INSET_UDP_SRC_PORT | IAVF_INSET_UDP_DST_PORT)
67 : :
68 : : #define IAVF_FDIR_INSET_ETH_IPV6_TCP (\
69 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
70 : : IAVF_INSET_IPV6_TC | IAVF_INSET_IPV6_HOP_LIMIT | \
71 : : IAVF_INSET_TCP_SRC_PORT | IAVF_INSET_TCP_DST_PORT)
72 : :
73 : : #define IAVF_FDIR_INSET_ETH_IPV6_SCTP (\
74 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
75 : : IAVF_INSET_IPV6_TC | IAVF_INSET_IPV6_HOP_LIMIT | \
76 : : IAVF_INSET_SCTP_SRC_PORT | IAVF_INSET_SCTP_DST_PORT)
77 : :
78 : : #define IAVF_FDIR_INSET_IPV4_GTPU (\
79 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
80 : : IAVF_INSET_GTPU_TEID)
81 : :
82 : : #define IAVF_FDIR_INSET_GTPU_IPV4 (\
83 : : IAVF_INSET_TUN_IPV4_SRC | IAVF_INSET_TUN_IPV4_DST | \
84 : : IAVF_INSET_TUN_IPV4_PROTO | IAVF_INSET_TUN_IPV4_TOS | \
85 : : IAVF_INSET_TUN_IPV4_TTL)
86 : :
87 : : #define IAVF_FDIR_INSET_GTPU_IPV4_UDP (\
88 : : IAVF_FDIR_INSET_GTPU_IPV4 | \
89 : : IAVF_INSET_TUN_UDP_SRC_PORT | IAVF_INSET_TUN_UDP_DST_PORT)
90 : :
91 : : #define IAVF_FDIR_INSET_GTPU_IPV4_TCP (\
92 : : IAVF_FDIR_INSET_GTPU_IPV4 | \
93 : : IAVF_INSET_TUN_TCP_SRC_PORT | IAVF_INSET_TUN_TCP_DST_PORT)
94 : :
95 : : #define IAVF_FDIR_INSET_IPV4_GTPU_EH (\
96 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
97 : : IAVF_INSET_GTPU_TEID | IAVF_INSET_GTPU_QFI)
98 : :
99 : : #define IAVF_FDIR_INSET_IPV6_GTPU (\
100 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
101 : : IAVF_INSET_GTPU_TEID)
102 : :
103 : : #define IAVF_FDIR_INSET_GTPU_IPV6 (\
104 : : IAVF_INSET_TUN_IPV6_SRC | IAVF_INSET_TUN_IPV6_DST | \
105 : : IAVF_INSET_TUN_IPV6_NEXT_HDR | IAVF_INSET_TUN_IPV6_TC | \
106 : : IAVF_INSET_TUN_IPV6_HOP_LIMIT)
107 : :
108 : : #define IAVF_FDIR_INSET_GTPU_IPV6_UDP (\
109 : : IAVF_FDIR_INSET_GTPU_IPV6 | \
110 : : IAVF_INSET_TUN_UDP_SRC_PORT | IAVF_INSET_TUN_UDP_DST_PORT)
111 : :
112 : : #define IAVF_FDIR_INSET_GTPU_IPV6_TCP (\
113 : : IAVF_FDIR_INSET_GTPU_IPV6 | \
114 : : IAVF_INSET_TUN_TCP_SRC_PORT | IAVF_INSET_TUN_TCP_DST_PORT)
115 : :
116 : : #define IAVF_FDIR_INSET_IPV6_GTPU_EH (\
117 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
118 : : IAVF_INSET_GTPU_TEID | IAVF_INSET_GTPU_QFI)
119 : :
120 : : #define IAVF_FDIR_INSET_L2TPV3OIP (\
121 : : IAVF_L2TPV3OIP_SESSION_ID)
122 : :
123 : : #define IAVF_FDIR_INSET_IPV4_ESP (\
124 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
125 : : IAVF_INSET_ESP_SPI)
126 : :
127 : : #define IAVF_FDIR_INSET_IPV6_ESP (\
128 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
129 : : IAVF_INSET_ESP_SPI)
130 : :
131 : : #define IAVF_FDIR_INSET_AH (\
132 : : IAVF_INSET_AH_SPI)
133 : :
134 : : #define IAVF_FDIR_INSET_IPV4_NATT_ESP (\
135 : : IAVF_INSET_IPV4_SRC | IAVF_INSET_IPV4_DST | \
136 : : IAVF_INSET_ESP_SPI)
137 : :
138 : : #define IAVF_FDIR_INSET_IPV6_NATT_ESP (\
139 : : IAVF_INSET_IPV6_SRC | IAVF_INSET_IPV6_DST | \
140 : : IAVF_INSET_ESP_SPI)
141 : :
142 : : #define IAVF_FDIR_INSET_PFCP (\
143 : : IAVF_INSET_PFCP_S_FIELD)
144 : :
145 : : #define IAVF_FDIR_INSET_ECPRI (\
146 : : IAVF_INSET_ECPRI)
147 : :
148 : : #define IAVF_FDIR_INSET_GRE_IPV4 (\
149 : : IAVF_INSET_TUN_IPV4_SRC | IAVF_INSET_TUN_IPV4_DST | \
150 : : IAVF_INSET_TUN_IPV4_TOS | IAVF_INSET_TUN_IPV4_PROTO)
151 : :
152 : : #define IAVF_FDIR_INSET_GRE_IPV4_TCP (\
153 : : IAVF_FDIR_INSET_GRE_IPV4 | IAVF_INSET_TUN_TCP_SRC_PORT | \
154 : : IAVF_INSET_TUN_TCP_DST_PORT)
155 : :
156 : : #define IAVF_FDIR_INSET_GRE_IPV4_UDP (\
157 : : IAVF_FDIR_INSET_GRE_IPV4 | IAVF_INSET_TUN_UDP_SRC_PORT | \
158 : : IAVF_INSET_TUN_UDP_DST_PORT)
159 : :
160 : : #define IAVF_FDIR_INSET_GRE_IPV6 (\
161 : : IAVF_INSET_TUN_IPV6_SRC | IAVF_INSET_TUN_IPV6_DST | \
162 : : IAVF_INSET_TUN_IPV6_TC | IAVF_INSET_TUN_IPV6_NEXT_HDR)
163 : :
164 : : #define IAVF_FDIR_INSET_GRE_IPV6_TCP (\
165 : : IAVF_FDIR_INSET_GRE_IPV6 | IAVF_INSET_TUN_TCP_SRC_PORT | \
166 : : IAVF_INSET_TUN_TCP_DST_PORT)
167 : :
168 : : #define IAVF_FDIR_INSET_GRE_IPV6_UDP (\
169 : : IAVF_FDIR_INSET_GRE_IPV6 | IAVF_INSET_TUN_UDP_SRC_PORT | \
170 : : IAVF_INSET_TUN_UDP_DST_PORT)
171 : :
172 : : #define IAVF_FDIR_INSET_L2TPV2 (\
173 : : IAVF_INSET_SMAC | IAVF_INSET_DMAC | IAVF_INSET_L2TPV2)
174 : :
175 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 (\
176 : : IAVF_INSET_TUN_IPV4_SRC | IAVF_INSET_TUN_IPV4_DST)
177 : :
178 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP (\
179 : : IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 | IAVF_INSET_TUN_UDP_SRC_PORT | \
180 : : IAVF_INSET_TUN_UDP_DST_PORT)
181 : :
182 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP (\
183 : : IAVF_FDIR_INSET_L2TPV2_PPP_IPV4 | IAVF_INSET_TUN_TCP_SRC_PORT | \
184 : : IAVF_INSET_TUN_TCP_DST_PORT)
185 : :
186 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 (\
187 : : IAVF_INSET_TUN_IPV6_SRC | IAVF_INSET_TUN_IPV6_DST)
188 : :
189 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP (\
190 : : IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 | IAVF_INSET_TUN_UDP_SRC_PORT | \
191 : : IAVF_INSET_TUN_UDP_DST_PORT)
192 : :
193 : : #define IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP (\
194 : : IAVF_FDIR_INSET_L2TPV2_PPP_IPV6 | IAVF_INSET_TUN_TCP_SRC_PORT | \
195 : : IAVF_INSET_TUN_TCP_DST_PORT)
196 : :
197 : : static struct iavf_pattern_match_item iavf_fdir_pattern[] = {
198 : : {iavf_pattern_raw, IAVF_INSET_NONE, IAVF_INSET_NONE},
199 : : {iavf_pattern_ethertype, IAVF_FDIR_INSET_ETH, IAVF_INSET_NONE},
200 : : {iavf_pattern_eth_ipv4, IAVF_FDIR_INSET_ETH_IPV4, IAVF_INSET_NONE},
201 : : {iavf_pattern_eth_ipv4_udp, IAVF_FDIR_INSET_ETH_IPV4_UDP, IAVF_INSET_NONE},
202 : : {iavf_pattern_eth_ipv4_tcp, IAVF_FDIR_INSET_ETH_IPV4_TCP, IAVF_INSET_NONE},
203 : : {iavf_pattern_eth_ipv4_sctp, IAVF_FDIR_INSET_ETH_IPV4_SCTP, IAVF_INSET_NONE},
204 : : {iavf_pattern_eth_ipv6, IAVF_FDIR_INSET_ETH_IPV6, IAVF_INSET_NONE},
205 : : {iavf_pattern_eth_ipv6_frag_ext, IAVF_FDIR_INSET_ETH_IPV6_FRAG_EXT, IAVF_INSET_NONE},
206 : : {iavf_pattern_eth_ipv6_udp, IAVF_FDIR_INSET_ETH_IPV6_UDP, IAVF_INSET_NONE},
207 : : {iavf_pattern_eth_ipv6_tcp, IAVF_FDIR_INSET_ETH_IPV6_TCP, IAVF_INSET_NONE},
208 : : {iavf_pattern_eth_ipv6_sctp, IAVF_FDIR_INSET_ETH_IPV6_SCTP, IAVF_INSET_NONE},
209 : : {iavf_pattern_eth_ipv4_gtpu, IAVF_FDIR_INSET_IPV4_GTPU, IAVF_INSET_NONE},
210 : : {iavf_pattern_eth_ipv4_gtpu_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
211 : : {iavf_pattern_eth_ipv4_gtpu_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
212 : : {iavf_pattern_eth_ipv4_gtpu_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
213 : : {iavf_pattern_eth_ipv4_gtpu_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
214 : : {iavf_pattern_eth_ipv4_gtpu_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
215 : : {iavf_pattern_eth_ipv4_gtpu_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
216 : : {iavf_pattern_eth_ipv4_gtpu_eh, IAVF_FDIR_INSET_IPV4_GTPU_EH, IAVF_INSET_NONE},
217 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
218 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
219 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
220 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
221 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
222 : : {iavf_pattern_eth_ipv4_gtpu_eh_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
223 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu, IAVF_FDIR_INSET_IPV4_GTPU, IAVF_INSET_NONE},
224 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
225 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
226 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
227 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
228 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
229 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
230 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu, IAVF_FDIR_INSET_IPV4_GTPU, IAVF_INSET_NONE},
231 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
232 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
233 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
234 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
235 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
236 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
237 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu, IAVF_FDIR_INSET_IPV6_GTPU, IAVF_INSET_NONE},
238 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
239 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
240 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
241 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
242 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
243 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
244 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu, IAVF_FDIR_INSET_IPV6_GTPU, IAVF_INSET_NONE},
245 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
246 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
247 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
248 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
249 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
250 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
251 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh, IAVF_FDIR_INSET_IPV4_GTPU_EH, IAVF_INSET_NONE},
252 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
253 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
254 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
255 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
256 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
257 : : {iavf_pattern_eth_ipv4_gre_ipv4_gtpu_eh_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
258 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh, IAVF_FDIR_INSET_IPV4_GTPU_EH, IAVF_INSET_NONE},
259 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
260 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
261 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
262 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
263 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
264 : : {iavf_pattern_eth_ipv4_gre_ipv6_gtpu_eh_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
265 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh, IAVF_FDIR_INSET_IPV6_GTPU_EH, IAVF_INSET_NONE},
266 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
267 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
268 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
269 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
270 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
271 : : {iavf_pattern_eth_ipv6_gre_ipv4_gtpu_eh_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
272 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh, IAVF_FDIR_INSET_IPV6_GTPU_EH, IAVF_INSET_NONE},
273 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4, IAVF_FDIR_INSET_GTPU_IPV4, IAVF_INSET_NONE},
274 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_udp, IAVF_FDIR_INSET_GTPU_IPV4_UDP, IAVF_INSET_NONE},
275 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv4_tcp, IAVF_FDIR_INSET_GTPU_IPV4_TCP, IAVF_INSET_NONE},
276 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6, IAVF_FDIR_INSET_GTPU_IPV6, IAVF_INSET_NONE},
277 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_udp, IAVF_FDIR_INSET_GTPU_IPV6_UDP, IAVF_INSET_NONE},
278 : : {iavf_pattern_eth_ipv6_gre_ipv6_gtpu_eh_ipv6_tcp, IAVF_FDIR_INSET_GTPU_IPV6_TCP, IAVF_INSET_NONE},
279 : : {iavf_pattern_eth_ipv6_gtpu, IAVF_FDIR_INSET_IPV6_GTPU, IAVF_INSET_NONE},
280 : : {iavf_pattern_eth_ipv6_gtpu_eh, IAVF_FDIR_INSET_IPV6_GTPU_EH, IAVF_INSET_NONE},
281 : : {iavf_pattern_eth_ipv4_l2tpv3, IAVF_FDIR_INSET_L2TPV3OIP, IAVF_INSET_NONE},
282 : : {iavf_pattern_eth_ipv6_l2tpv3, IAVF_FDIR_INSET_L2TPV3OIP, IAVF_INSET_NONE},
283 : : {iavf_pattern_eth_ipv4_esp, IAVF_FDIR_INSET_IPV4_ESP, IAVF_INSET_NONE},
284 : : {iavf_pattern_eth_ipv6_esp, IAVF_FDIR_INSET_IPV6_ESP, IAVF_INSET_NONE},
285 : : {iavf_pattern_eth_ipv4_ah, IAVF_FDIR_INSET_AH, IAVF_INSET_NONE},
286 : : {iavf_pattern_eth_ipv6_ah, IAVF_FDIR_INSET_AH, IAVF_INSET_NONE},
287 : : {iavf_pattern_eth_ipv4_udp_esp, IAVF_FDIR_INSET_IPV4_NATT_ESP, IAVF_INSET_NONE},
288 : : {iavf_pattern_eth_ipv6_udp_esp, IAVF_FDIR_INSET_IPV6_NATT_ESP, IAVF_INSET_NONE},
289 : : {iavf_pattern_eth_ipv4_pfcp, IAVF_FDIR_INSET_PFCP, IAVF_INSET_NONE},
290 : : {iavf_pattern_eth_ipv6_pfcp, IAVF_FDIR_INSET_PFCP, IAVF_INSET_NONE},
291 : : {iavf_pattern_eth_ecpri, IAVF_FDIR_INSET_ECPRI, IAVF_INSET_NONE},
292 : : {iavf_pattern_eth_ipv4_ecpri, IAVF_FDIR_INSET_ECPRI, IAVF_INSET_NONE},
293 : : {iavf_pattern_eth_ipv4_gre_ipv4, IAVF_FDIR_INSET_GRE_IPV4, IAVF_INSET_NONE},
294 : : {iavf_pattern_eth_ipv4_gre_ipv4_tcp, IAVF_FDIR_INSET_GRE_IPV4_TCP, IAVF_INSET_NONE},
295 : : {iavf_pattern_eth_ipv4_gre_ipv4_udp, IAVF_FDIR_INSET_GRE_IPV4_UDP, IAVF_INSET_NONE},
296 : : {iavf_pattern_eth_ipv4_gre_ipv6, IAVF_FDIR_INSET_GRE_IPV6, IAVF_INSET_NONE},
297 : : {iavf_pattern_eth_ipv4_gre_ipv6_tcp, IAVF_FDIR_INSET_GRE_IPV6_TCP, IAVF_INSET_NONE},
298 : : {iavf_pattern_eth_ipv4_gre_ipv6_udp, IAVF_FDIR_INSET_GRE_IPV6_UDP, IAVF_INSET_NONE},
299 : : {iavf_pattern_eth_ipv6_gre_ipv4, IAVF_FDIR_INSET_GRE_IPV4, IAVF_INSET_NONE},
300 : : {iavf_pattern_eth_ipv6_gre_ipv4_tcp, IAVF_FDIR_INSET_GRE_IPV4_TCP, IAVF_INSET_NONE},
301 : : {iavf_pattern_eth_ipv6_gre_ipv4_udp, IAVF_FDIR_INSET_GRE_IPV4_UDP, IAVF_INSET_NONE},
302 : : {iavf_pattern_eth_ipv6_gre_ipv6, IAVF_FDIR_INSET_GRE_IPV6, IAVF_INSET_NONE},
303 : : {iavf_pattern_eth_ipv6_gre_ipv6_tcp, IAVF_FDIR_INSET_GRE_IPV6_TCP, IAVF_INSET_NONE},
304 : : {iavf_pattern_eth_ipv6_gre_ipv6_udp, IAVF_FDIR_INSET_GRE_IPV6_UDP, IAVF_INSET_NONE},
305 : :
306 : : {iavf_pattern_eth_ipv4_udp_l2tpv2, IAVF_FDIR_INSET_L2TPV2, IAVF_INSET_NONE},
307 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp, IAVF_FDIR_INSET_L2TPV2, IAVF_INSET_NONE},
308 : : {iavf_pattern_eth_ipv6_udp_l2tpv2, IAVF_FDIR_INSET_L2TPV2, IAVF_INSET_NONE},
309 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp, IAVF_FDIR_INSET_L2TPV2, IAVF_INSET_NONE},
310 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4, IAVF_INSET_NONE},
311 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP, IAVF_INSET_NONE},
312 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv4_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP, IAVF_INSET_NONE},
313 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4, IAVF_INSET_NONE},
314 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_UDP, IAVF_INSET_NONE},
315 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv4_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV4_TCP, IAVF_INSET_NONE},
316 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6, IAVF_INSET_NONE},
317 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP, IAVF_INSET_NONE},
318 : : {iavf_pattern_eth_ipv4_udp_l2tpv2_ppp_ipv6_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP, IAVF_INSET_NONE},
319 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6, IAVF_INSET_NONE},
320 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_udp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_UDP, IAVF_INSET_NONE},
321 : : {iavf_pattern_eth_ipv6_udp_l2tpv2_ppp_ipv6_tcp, IAVF_FDIR_INSET_L2TPV2_PPP_IPV6_TCP, IAVF_INSET_NONE},
322 : : };
323 : :
324 : : static struct iavf_flow_parser iavf_fdir_parser;
325 : :
326 : : static int
327 : 0 : iavf_fdir_init(struct iavf_adapter *ad)
328 : : {
329 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
330 : : struct iavf_flow_parser *parser;
331 : :
332 [ # # ]: 0 : if (!vf->vf_res)
333 : : return -EINVAL;
334 : :
335 [ # # ]: 0 : if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_FDIR_PF)
336 : : parser = &iavf_fdir_parser;
337 : : else
338 : : return -ENOTSUP;
339 : :
340 : 0 : return iavf_register_parser(parser, ad);
341 : : }
342 : :
343 : : static void
344 : 0 : iavf_fdir_uninit(struct iavf_adapter *ad)
345 : : {
346 : 0 : iavf_unregister_parser(&iavf_fdir_parser, ad);
347 : 0 : }
348 : :
349 : : static int
350 : 0 : iavf_fdir_create(struct iavf_adapter *ad,
351 : : struct rte_flow *flow,
352 : : void *meta,
353 : : struct rte_flow_error *error)
354 : : {
355 : : struct iavf_fdir_conf *filter = meta;
356 : : struct iavf_fdir_conf *rule;
357 : : int ret;
358 : :
359 : 0 : rule = rte_zmalloc("fdir_entry", sizeof(*rule), 0);
360 [ # # ]: 0 : if (!rule) {
361 : 0 : rte_flow_error_set(error, ENOMEM,
362 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
363 : : "Failed to allocate memory for fdir rule");
364 : 0 : return -rte_errno;
365 : : }
366 : :
367 : 0 : ret = iavf_fdir_add(ad, filter);
368 [ # # ]: 0 : if (ret) {
369 : 0 : rte_flow_error_set(error, -ret,
370 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
371 : : "Failed to add filter rule.");
372 : 0 : goto free_entry;
373 : : }
374 : :
375 [ # # ]: 0 : if (filter->mark_flag == 1)
376 : 0 : iavf_fdir_rx_proc_enable(ad, 1);
377 : :
378 : : memcpy(rule, filter, sizeof(*rule));
379 : 0 : flow->rule = rule;
380 : :
381 : 0 : return 0;
382 : :
383 : : free_entry:
384 : 0 : rte_free(rule);
385 : 0 : return -rte_errno;
386 : : }
387 : :
388 : : static int
389 : 0 : iavf_fdir_destroy(struct iavf_adapter *ad,
390 : : struct rte_flow *flow,
391 : : struct rte_flow_error *error)
392 : : {
393 : : struct iavf_fdir_conf *filter;
394 : : int ret;
395 : :
396 : 0 : filter = (struct iavf_fdir_conf *)flow->rule;
397 : :
398 : 0 : ret = iavf_fdir_del(ad, filter);
399 [ # # ]: 0 : if (ret) {
400 : 0 : rte_flow_error_set(error, -ret,
401 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
402 : : "Failed to delete filter rule.");
403 : 0 : return -rte_errno;
404 : : }
405 : :
406 [ # # ]: 0 : if (filter->mark_flag == 1)
407 : 0 : iavf_fdir_rx_proc_enable(ad, 0);
408 : :
409 : 0 : flow->rule = NULL;
410 : 0 : rte_free(filter);
411 : :
412 : 0 : return 0;
413 : : }
414 : :
415 : : static int
416 : 0 : iavf_fdir_validation(struct iavf_adapter *ad,
417 : : __rte_unused struct rte_flow *flow,
418 : : void *meta,
419 : : struct rte_flow_error *error)
420 : : {
421 : : struct iavf_fdir_conf *filter = meta;
422 : : int ret;
423 : :
424 : 0 : ret = iavf_fdir_check(ad, filter);
425 [ # # ]: 0 : if (ret) {
426 : 0 : rte_flow_error_set(error, -ret,
427 : : RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
428 : : "Failed to validate filter rule.");
429 : 0 : return -rte_errno;
430 : : }
431 : :
432 : : return 0;
433 : : };
434 : :
435 : : static struct iavf_flow_engine iavf_fdir_engine = {
436 : : .init = iavf_fdir_init,
437 : : .uninit = iavf_fdir_uninit,
438 : : .create = iavf_fdir_create,
439 : : .destroy = iavf_fdir_destroy,
440 : : .validation = iavf_fdir_validation,
441 : : .name = "fdir",
442 : : .type = IAVF_FLOW_ENGINE_FDIR,
443 : : .rule_size = sizeof(struct iavf_fdir_conf),
444 : : };
445 : :
446 : : static bool
447 : 0 : iavf_fdir_refine_input_set(const uint64_t input_set,
448 : : const uint64_t input_set_mask,
449 : : struct iavf_fdir_conf *filter)
450 : : {
451 : : struct virtchnl_proto_hdr *hdr, *hdr_last;
452 : : struct rte_flow_item_ipv4 ipv4_spec;
453 : : struct rte_flow_item_ipv6 ipv6_spec;
454 : : int last_layer;
455 : : uint8_t proto_id;
456 : :
457 [ # # ]: 0 : if (input_set & ~input_set_mask)
458 : : return false;
459 [ # # ]: 0 : else if (input_set)
460 : : return true;
461 : :
462 : 0 : last_layer = filter->add_fltr.rule_cfg.proto_hdrs.count - 1;
463 : : /* Last layer of TCP/UDP pattern isn't less than 2. */
464 [ # # ]: 0 : if (last_layer < 2)
465 : : return false;
466 : : hdr_last = &filter->add_fltr.rule_cfg.proto_hdrs.proto_hdr[last_layer];
467 [ # # ]: 0 : if (hdr_last->type == VIRTCHNL_PROTO_HDR_TCP)
468 : : proto_id = 6;
469 [ # # ]: 0 : else if (hdr_last->type == VIRTCHNL_PROTO_HDR_UDP)
470 : : proto_id = 17;
471 : : else
472 : : return false;
473 : :
474 : 0 : hdr = &filter->add_fltr.rule_cfg.proto_hdrs.proto_hdr[last_layer - 1];
475 [ # # # ]: 0 : switch (hdr->type) {
476 : 0 : case VIRTCHNL_PROTO_HDR_IPV4:
477 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, PROT);
478 : : memset(&ipv4_spec, 0, sizeof(ipv4_spec));
479 : 0 : ipv4_spec.hdr.next_proto_id = proto_id;
480 : 0 : memcpy(hdr->buffer, &ipv4_spec.hdr,
481 : : sizeof(ipv4_spec.hdr));
482 : 0 : return true;
483 : 0 : case VIRTCHNL_PROTO_HDR_IPV6:
484 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, PROT);
485 : : memset(&ipv6_spec, 0, sizeof(ipv6_spec));
486 : 0 : ipv6_spec.hdr.proto = proto_id;
487 : 0 : memcpy(hdr->buffer, &ipv6_spec.hdr,
488 : : sizeof(ipv6_spec.hdr));
489 : 0 : return true;
490 : : default:
491 : : return false;
492 : : }
493 : : }
494 : :
495 : : static void
496 : 0 : iavf_fdir_add_fragment_hdr(struct virtchnl_proto_hdrs *hdrs, int layer)
497 : : {
498 : : struct virtchnl_proto_hdr *hdr1;
499 : : struct virtchnl_proto_hdr *hdr2;
500 : : int i;
501 : :
502 [ # # # # ]: 0 : if (layer < 0 || layer > hdrs->count)
503 : : return;
504 : :
505 : : /* shift headers layer */
506 [ # # ]: 0 : for (i = hdrs->count; i >= layer; i--) {
507 : : hdr1 = &hdrs->proto_hdr[i];
508 : 0 : hdr2 = &hdrs->proto_hdr[i - 1];
509 : 0 : *hdr1 = *hdr2;
510 : : }
511 : :
512 : : /* adding dummy fragment header */
513 : : hdr1 = &hdrs->proto_hdr[layer];
514 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, IPV4_FRAG);
515 : 0 : hdr1->field_selector = 0;
516 : 0 : hdrs->count = ++layer;
517 : : }
518 : :
519 : : static int
520 : 0 : iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad,
521 : : const struct rte_flow_item pattern[],
522 : : const uint64_t input_set_mask,
523 : : struct rte_flow_error *error,
524 : : struct iavf_fdir_conf *filter)
525 : : {
526 : 0 : struct virtchnl_proto_hdrs *hdrs =
527 : : &filter->add_fltr.rule_cfg.proto_hdrs;
528 : : enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END;
529 : : const struct rte_flow_item_raw *raw_spec, *raw_mask;
530 : : const struct rte_flow_item_eth *eth_spec, *eth_mask;
531 : : const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask;
532 : : const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
533 : : const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_spec;
534 : : const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_mask;
535 : : const struct rte_flow_item_udp *udp_spec, *udp_mask;
536 : : const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
537 : : const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
538 : : const struct rte_flow_item_gtp *gtp_spec, *gtp_mask;
539 : : const struct rte_flow_item_gtp_psc *gtp_psc_spec, *gtp_psc_mask;
540 : : const struct rte_flow_item_l2tpv3oip *l2tpv3oip_spec, *l2tpv3oip_mask;
541 : : const struct rte_flow_item_esp *esp_spec, *esp_mask;
542 : : const struct rte_flow_item_ah *ah_spec, *ah_mask;
543 : : const struct rte_flow_item_pfcp *pfcp_spec, *pfcp_mask;
544 : : const struct rte_flow_item_ecpri *ecpri_spec, *ecpri_mask;
545 : : const struct rte_flow_item_gre *gre_spec, *gre_mask;
546 : : const struct rte_flow_item_l2tpv2 *l2tpv2_spec, *l2tpv2_mask;
547 : : const struct rte_flow_item_ppp *ppp_spec, *ppp_mask;
548 : : const struct rte_flow_item *item = pattern;
549 : : struct virtchnl_proto_hdr *hdr, *hdr1 = NULL;
550 : : struct rte_ecpri_common_hdr ecpri_common;
551 : : uint64_t input_set = IAVF_INSET_NONE;
552 : : enum rte_flow_item_type item_type;
553 : : enum rte_flow_item_type next_type;
554 : : uint8_t tun_inner = 0;
555 : : uint16_t ether_type, flags_version;
556 : : uint8_t item_num = 0;
557 : : int layer = 0;
558 : :
559 : 0 : uint8_t ipv6_addr_mask[16] = {
560 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
561 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
562 : : };
563 : :
564 [ # # ]: 0 : for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
565 : : item_type = item->type;
566 : :
567 [ # # ]: 0 : if (item->last && !(item_type == RTE_FLOW_ITEM_TYPE_IPV4 ||
568 [ # # ]: 0 : item_type ==
569 : : RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT)) {
570 : 0 : rte_flow_error_set(error, EINVAL,
571 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
572 : : "Not support range");
573 : : }
574 : 0 : item_num++;
575 : :
576 [ # # # # : 0 : switch (item_type) {
# # # # #
# # # # #
# # # # #
# ]
577 : 0 : case RTE_FLOW_ITEM_TYPE_RAW: {
578 : 0 : raw_spec = item->spec;
579 : 0 : raw_mask = item->mask;
580 : :
581 [ # # ]: 0 : if (!raw_spec || !raw_mask) {
582 : 0 : PMD_DRV_LOG(ERR, "NULL RAW spec/mask");
583 : 0 : rte_flow_error_set(error, EINVAL,
584 : : RTE_FLOW_ERROR_TYPE_ITEM,
585 : : item,
586 : : "NULL RAW spec/mask");
587 : 0 : return -rte_errno;
588 : : }
589 : :
590 [ # # ]: 0 : if (item_num != 1)
591 : 0 : return -rte_errno;
592 : :
593 [ # # ]: 0 : if (raw_spec->length != raw_mask->length)
594 : 0 : return -rte_errno;
595 : :
596 : : uint16_t pkt_len = 0;
597 : : uint16_t tmp_val = 0;
598 : : uint8_t tmp = 0;
599 : : int i, j;
600 : :
601 : : pkt_len = raw_spec->length;
602 : :
603 [ # # ]: 0 : for (i = 0, j = 0; i < pkt_len; i += 2, j++) {
604 : 0 : tmp = raw_spec->pattern[i];
605 [ # # ]: 0 : if (tmp >= 'a' && tmp <= 'f')
606 : 0 : tmp_val = tmp - 'a' + 10;
607 [ # # ]: 0 : if (tmp >= 'A' && tmp <= 'F')
608 : 0 : tmp_val = tmp - 'A' + 10;
609 [ # # ]: 0 : if (tmp >= '0' && tmp <= '9')
610 : 0 : tmp_val = tmp - '0';
611 : :
612 : 0 : tmp_val *= 16;
613 : 0 : tmp = raw_spec->pattern[i + 1];
614 [ # # ]: 0 : if (tmp >= 'a' && tmp <= 'f')
615 : 0 : tmp_val += (tmp - 'a' + 10);
616 [ # # ]: 0 : if (tmp >= 'A' && tmp <= 'F')
617 : 0 : tmp_val += (tmp - 'A' + 10);
618 [ # # ]: 0 : if (tmp >= '0' && tmp <= '9')
619 : 0 : tmp_val += (tmp - '0');
620 : :
621 : 0 : hdrs->raw.spec[j] = tmp_val;
622 : :
623 : 0 : tmp = raw_mask->pattern[i];
624 [ # # ]: 0 : if (tmp >= 'a' && tmp <= 'f')
625 : 0 : tmp_val = tmp - 'a' + 10;
626 [ # # ]: 0 : if (tmp >= 'A' && tmp <= 'F')
627 : 0 : tmp_val = tmp - 'A' + 10;
628 [ # # ]: 0 : if (tmp >= '0' && tmp <= '9')
629 : 0 : tmp_val = tmp - '0';
630 : :
631 : 0 : tmp_val *= 16;
632 : 0 : tmp = raw_mask->pattern[i + 1];
633 [ # # ]: 0 : if (tmp >= 'a' && tmp <= 'f')
634 : 0 : tmp_val += (tmp - 'a' + 10);
635 [ # # ]: 0 : if (tmp >= 'A' && tmp <= 'F')
636 : 0 : tmp_val += (tmp - 'A' + 10);
637 [ # # ]: 0 : if (tmp >= '0' && tmp <= '9')
638 : 0 : tmp_val += (tmp - '0');
639 : :
640 : 0 : hdrs->raw.mask[j] = tmp_val;
641 : : }
642 : :
643 : 0 : hdrs->raw.pkt_len = pkt_len / 2;
644 : 0 : hdrs->tunnel_level = 0;
645 : 0 : hdrs->count = 0;
646 : 0 : return 0;
647 : : }
648 : :
649 : 0 : case RTE_FLOW_ITEM_TYPE_ETH:
650 : 0 : eth_spec = item->spec;
651 : 0 : eth_mask = item->mask;
652 : 0 : next_type = (item + 1)->type;
653 : :
654 : 0 : hdr1 = &hdrs->proto_hdr[layer];
655 : :
656 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr1, ETH);
657 : :
658 [ # # ]: 0 : if (next_type == RTE_FLOW_ITEM_TYPE_END &&
659 [ # # ]: 0 : (!eth_spec || !eth_mask)) {
660 : 0 : rte_flow_error_set(error, EINVAL,
661 : : RTE_FLOW_ERROR_TYPE_ITEM,
662 : : item, "NULL eth spec/mask.");
663 : 0 : return -rte_errno;
664 : : }
665 : :
666 [ # # ]: 0 : if (eth_spec && eth_mask) {
667 [ # # ]: 0 : if (!rte_is_zero_ether_addr(ð_mask->hdr.dst_addr)) {
668 : 0 : input_set |= IAVF_INSET_DMAC;
669 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1,
670 : : ETH,
671 : : DST);
672 [ # # ]: 0 : } else if (!rte_is_zero_ether_addr(ð_mask->hdr.src_addr)) {
673 : 0 : input_set |= IAVF_INSET_SMAC;
674 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1,
675 : : ETH,
676 : : SRC);
677 : : }
678 : :
679 [ # # ]: 0 : if (eth_mask->hdr.ether_type) {
680 [ # # ]: 0 : if (eth_mask->hdr.ether_type != RTE_BE16(0xffff)) {
681 : 0 : rte_flow_error_set(error, EINVAL,
682 : : RTE_FLOW_ERROR_TYPE_ITEM,
683 : : item, "Invalid type mask.");
684 : 0 : return -rte_errno;
685 : : }
686 : :
687 [ # # ]: 0 : ether_type = rte_be_to_cpu_16(eth_spec->hdr.ether_type);
688 : 0 : if (ether_type == RTE_ETHER_TYPE_IPV4 ||
689 [ # # ]: 0 : ether_type == RTE_ETHER_TYPE_IPV6) {
690 : 0 : rte_flow_error_set(error, EINVAL,
691 : : RTE_FLOW_ERROR_TYPE_ITEM,
692 : : item,
693 : : "Unsupported ether_type.");
694 : 0 : return -rte_errno;
695 : : }
696 : :
697 : 0 : input_set |= IAVF_INSET_ETHERTYPE;
698 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
699 : : ETHERTYPE);
700 : : }
701 : :
702 : 0 : memcpy(hdr1->buffer, eth_spec,
703 : : sizeof(struct rte_ether_hdr));
704 : : }
705 : :
706 : 0 : hdrs->count = ++layer;
707 : 0 : break;
708 : :
709 : 0 : case RTE_FLOW_ITEM_TYPE_IPV4:
710 : : l3 = RTE_FLOW_ITEM_TYPE_IPV4;
711 : 0 : ipv4_spec = item->spec;
712 : 0 : ipv4_last = item->last;
713 : 0 : ipv4_mask = item->mask;
714 : : next_type = (item + 1)->type;
715 : :
716 : : hdr = &hdrs->proto_hdr[layer];
717 : :
718 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4);
719 : :
720 [ # # ]: 0 : if (!(ipv4_spec && ipv4_mask)) {
721 : 0 : hdrs->count = ++layer;
722 : 0 : break;
723 : : }
724 : :
725 [ # # ]: 0 : if (ipv4_mask->hdr.version_ihl ||
726 [ # # ]: 0 : ipv4_mask->hdr.total_length ||
727 [ # # ]: 0 : ipv4_mask->hdr.hdr_checksum) {
728 : 0 : rte_flow_error_set(error, EINVAL,
729 : : RTE_FLOW_ERROR_TYPE_ITEM,
730 : : item, "Invalid IPv4 mask.");
731 : 0 : return -rte_errno;
732 : : }
733 : :
734 [ # # ]: 0 : if (ipv4_last &&
735 [ # # ]: 0 : (ipv4_last->hdr.version_ihl ||
736 : 0 : ipv4_last->hdr.type_of_service ||
737 [ # # ]: 0 : ipv4_last->hdr.time_to_live ||
738 : 0 : ipv4_last->hdr.total_length |
739 [ # # ]: 0 : ipv4_last->hdr.next_proto_id ||
740 [ # # ]: 0 : ipv4_last->hdr.hdr_checksum ||
741 [ # # ]: 0 : ipv4_last->hdr.src_addr ||
742 [ # # ]: 0 : ipv4_last->hdr.dst_addr)) {
743 : 0 : rte_flow_error_set(error, EINVAL,
744 : : RTE_FLOW_ERROR_TYPE_ITEM,
745 : : item, "Invalid IPv4 last.");
746 : 0 : return -rte_errno;
747 : : }
748 : :
749 : : /* Mask for IPv4 src/dst addrs not supported */
750 [ # # ]: 0 : if (ipv4_mask->hdr.src_addr &&
751 : : ipv4_mask->hdr.src_addr != UINT32_MAX)
752 : 0 : return -rte_errno;
753 [ # # ]: 0 : if (ipv4_mask->hdr.dst_addr &&
754 : : ipv4_mask->hdr.dst_addr != UINT32_MAX)
755 : 0 : return -rte_errno;
756 : :
757 [ # # ]: 0 : if (ipv4_mask->hdr.type_of_service ==
758 : : UINT8_MAX) {
759 : 0 : input_set |= IAVF_INSET_IPV4_TOS;
760 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4,
761 : : DSCP);
762 : : }
763 : :
764 [ # # ]: 0 : if (ipv4_mask->hdr.next_proto_id == UINT8_MAX) {
765 : 0 : input_set |= IAVF_INSET_IPV4_PROTO;
766 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4,
767 : : PROT);
768 : : }
769 : :
770 [ # # ]: 0 : if (ipv4_mask->hdr.time_to_live == UINT8_MAX) {
771 : 0 : input_set |= IAVF_INSET_IPV4_TTL;
772 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4,
773 : : TTL);
774 : : }
775 : :
776 [ # # ]: 0 : if (ipv4_mask->hdr.src_addr == UINT32_MAX) {
777 : 0 : input_set |= IAVF_INSET_IPV4_SRC;
778 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4,
779 : : SRC);
780 : : }
781 : :
782 [ # # ]: 0 : if (ipv4_mask->hdr.dst_addr == UINT32_MAX) {
783 : 0 : input_set |= IAVF_INSET_IPV4_DST;
784 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4,
785 : : DST);
786 : : }
787 : :
788 [ # # ]: 0 : if (tun_inner) {
789 : 0 : input_set &= ~IAVF_PROT_IPV4_OUTER;
790 : 0 : input_set |= IAVF_PROT_IPV4_INNER;
791 : : }
792 : :
793 [ # # ]: 0 : memcpy(hdr->buffer, &ipv4_spec->hdr,
794 : : sizeof(ipv4_spec->hdr));
795 : :
796 : 0 : hdrs->count = ++layer;
797 : :
798 : : /* fragment Ipv4:
799 : : * spec is 0x2000, mask is 0x2000
800 : : */
801 [ # # ]: 0 : if (ipv4_spec->hdr.fragment_offset ==
802 : 0 : rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG) &&
803 [ # # ]: 0 : ipv4_mask->hdr.fragment_offset ==
804 : : rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG)) {
805 : : /* all IPv4 fragment packet has the same
806 : : * ethertype, if the spec and mask is valid,
807 : : * set ethertype into input set.
808 : : */
809 : : /* ETH should be present via pattern pre-validation. */
810 [ # # ]: 0 : if (hdr1 == NULL) {
811 : 0 : rte_flow_error_set(error, EINVAL,
812 : : RTE_FLOW_ERROR_TYPE_ITEM,
813 : : item,
814 : : "Missing ETH header before IPv4 fragment.");
815 : 0 : return -rte_errno;
816 : : }
817 : 0 : input_set |= IAVF_INSET_ETHERTYPE;
818 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
819 : : ETHERTYPE);
820 : :
821 : : /* add dummy header for IPv4 Fragment */
822 : 0 : iavf_fdir_add_fragment_hdr(hdrs, layer);
823 [ # # ]: 0 : } else if (ipv4_mask->hdr.packet_id == UINT16_MAX) {
824 : 0 : rte_flow_error_set(error, EINVAL,
825 : : RTE_FLOW_ERROR_TYPE_ITEM,
826 : : item, "Invalid IPv4 mask.");
827 : 0 : return -rte_errno;
828 : : }
829 : :
830 : : break;
831 : :
832 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6:
833 : : l3 = RTE_FLOW_ITEM_TYPE_IPV6;
834 : 0 : ipv6_spec = item->spec;
835 : 0 : ipv6_mask = item->mask;
836 : :
837 : : hdr = &hdrs->proto_hdr[layer];
838 : :
839 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6);
840 : :
841 [ # # ]: 0 : if (!(ipv6_spec && ipv6_mask)) {
842 : 0 : hdrs->count = ++layer;
843 : 0 : break;
844 : : }
845 : :
846 [ # # ]: 0 : if (ipv6_mask->hdr.payload_len) {
847 : 0 : rte_flow_error_set(error, EINVAL,
848 : : RTE_FLOW_ERROR_TYPE_ITEM,
849 : : item, "Invalid IPv6 mask");
850 : 0 : return -rte_errno;
851 : : }
852 : :
853 [ # # ]: 0 : if ((ipv6_mask->hdr.vtc_flow &
854 : : rte_cpu_to_be_32(IAVF_IPV6_TC_MASK))
855 : : == rte_cpu_to_be_32(IAVF_IPV6_TC_MASK)) {
856 : 0 : input_set |= IAVF_INSET_IPV6_TC;
857 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
858 : : TC);
859 : : }
860 : :
861 [ # # ]: 0 : if (ipv6_mask->hdr.proto == UINT8_MAX) {
862 : 0 : input_set |= IAVF_INSET_IPV6_NEXT_HDR;
863 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
864 : : PROT);
865 : : }
866 : :
867 [ # # ]: 0 : if (ipv6_mask->hdr.hop_limits == UINT8_MAX) {
868 : 0 : input_set |= IAVF_INSET_IPV6_HOP_LIMIT;
869 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
870 : : HOP_LIMIT);
871 : : }
872 : :
873 [ # # ]: 0 : if (!memcmp(&ipv6_mask->hdr.src_addr, ipv6_addr_mask,
874 : : sizeof(ipv6_mask->hdr.src_addr))) {
875 : 0 : input_set |= IAVF_INSET_IPV6_SRC;
876 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
877 : : SRC);
878 : : }
879 [ # # ]: 0 : if (!memcmp(&ipv6_mask->hdr.dst_addr, ipv6_addr_mask,
880 : : sizeof(ipv6_mask->hdr.dst_addr))) {
881 : 0 : input_set |= IAVF_INSET_IPV6_DST;
882 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
883 : : DST);
884 : : }
885 : :
886 [ # # ]: 0 : if (tun_inner) {
887 : 0 : input_set &= ~IAVF_PROT_IPV6_OUTER;
888 : 0 : input_set |= IAVF_PROT_IPV6_INNER;
889 : : }
890 : :
891 : 0 : memcpy(hdr->buffer, &ipv6_spec->hdr,
892 : : sizeof(ipv6_spec->hdr));
893 : :
894 : 0 : hdrs->count = ++layer;
895 : 0 : break;
896 : :
897 : 0 : case RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT:
898 : 0 : ipv6_frag_spec = item->spec;
899 : 0 : ipv6_frag_mask = item->mask;
900 : : next_type = (item + 1)->type;
901 : :
902 : : hdr = &hdrs->proto_hdr[layer];
903 : :
904 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6_EH_FRAG);
905 : :
906 [ # # ]: 0 : if (!(ipv6_frag_spec && ipv6_frag_mask)) {
907 : 0 : hdrs->count = ++layer;
908 : 0 : break;
909 : : }
910 : :
911 : : /* fragment Ipv6:
912 : : * spec is 0x1, mask is 0x1
913 : : */
914 [ # # ]: 0 : if (ipv6_frag_spec->hdr.frag_data ==
915 : 0 : rte_cpu_to_be_16(1) &&
916 [ # # ]: 0 : ipv6_frag_mask->hdr.frag_data ==
917 : : rte_cpu_to_be_16(1)) {
918 : : /* all IPv6 fragment packet has the same
919 : : * ethertype, if the spec and mask is valid,
920 : : * set ethertype into input set.
921 : : */
922 : : /* ETH should be present via pattern pre-validation. */
923 [ # # ]: 0 : if (hdr1 == NULL) {
924 : 0 : rte_flow_error_set(error, EINVAL,
925 : : RTE_FLOW_ERROR_TYPE_ITEM,
926 : : item,
927 : : "Missing ETH header before IPv6 fragment.");
928 : 0 : return -rte_errno;
929 : : }
930 : 0 : input_set |= IAVF_INSET_ETHERTYPE;
931 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
932 : : ETHERTYPE);
933 : :
934 : 0 : memcpy(hdr->buffer, &ipv6_frag_spec->hdr,
935 : : sizeof(ipv6_frag_spec->hdr));
936 [ # # ]: 0 : } else if (ipv6_frag_mask->hdr.id == UINT32_MAX) {
937 : 0 : rte_flow_error_set(error, EINVAL,
938 : : RTE_FLOW_ERROR_TYPE_ITEM,
939 : : item, "Invalid IPv6 mask.");
940 : 0 : return -rte_errno;
941 : : }
942 : :
943 : 0 : hdrs->count = ++layer;
944 : 0 : break;
945 : :
946 : 0 : case RTE_FLOW_ITEM_TYPE_UDP:
947 : 0 : udp_spec = item->spec;
948 : 0 : udp_mask = item->mask;
949 : :
950 : : hdr = &hdrs->proto_hdr[layer];
951 : :
952 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP);
953 : :
954 [ # # ]: 0 : if (udp_spec && udp_mask) {
955 [ # # ]: 0 : if (udp_mask->hdr.dgram_len ||
956 [ # # ]: 0 : udp_mask->hdr.dgram_cksum) {
957 : 0 : rte_flow_error_set(error, EINVAL,
958 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
959 : : "Invalid UDP mask");
960 : 0 : return -rte_errno;
961 : : }
962 : :
963 : : /* Mask for UDP src/dst ports not supported */
964 [ # # ]: 0 : if (udp_mask->hdr.src_port &&
965 : : udp_mask->hdr.src_port != UINT16_MAX)
966 : 0 : return -rte_errno;
967 [ # # ]: 0 : if (udp_mask->hdr.dst_port &&
968 : : udp_mask->hdr.dst_port != UINT16_MAX)
969 : 0 : return -rte_errno;
970 : :
971 [ # # ]: 0 : if (udp_mask->hdr.src_port == UINT16_MAX) {
972 : 0 : input_set |= IAVF_INSET_UDP_SRC_PORT;
973 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT);
974 : : }
975 [ # # ]: 0 : if (udp_mask->hdr.dst_port == UINT16_MAX) {
976 : 0 : input_set |= IAVF_INSET_UDP_DST_PORT;
977 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT);
978 : : }
979 : :
980 [ # # ]: 0 : if (tun_inner) {
981 : 0 : input_set &= ~IAVF_PROT_UDP_OUTER;
982 : 0 : input_set |= IAVF_PROT_UDP_INNER;
983 : : }
984 : :
985 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
986 : 0 : memcpy(hdr->buffer,
987 : 0 : &udp_spec->hdr,
988 : : sizeof(udp_spec->hdr));
989 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
990 : 0 : memcpy(hdr->buffer,
991 : 0 : &udp_spec->hdr,
992 : : sizeof(udp_spec->hdr));
993 : : }
994 : :
995 : 0 : hdrs->count = ++layer;
996 : 0 : break;
997 : :
998 : 0 : case RTE_FLOW_ITEM_TYPE_TCP:
999 : 0 : tcp_spec = item->spec;
1000 : 0 : tcp_mask = item->mask;
1001 : :
1002 : : hdr = &hdrs->proto_hdr[layer];
1003 : :
1004 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP);
1005 : :
1006 [ # # ]: 0 : if (tcp_spec && tcp_mask) {
1007 [ # # ]: 0 : if (tcp_mask->hdr.sent_seq ||
1008 [ # # ]: 0 : tcp_mask->hdr.recv_ack ||
1009 [ # # ]: 0 : tcp_mask->hdr.data_off ||
1010 [ # # ]: 0 : tcp_mask->hdr.tcp_flags ||
1011 [ # # ]: 0 : tcp_mask->hdr.rx_win ||
1012 [ # # ]: 0 : tcp_mask->hdr.cksum ||
1013 [ # # ]: 0 : tcp_mask->hdr.tcp_urp) {
1014 : 0 : rte_flow_error_set(error, EINVAL,
1015 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
1016 : : "Invalid TCP mask");
1017 : 0 : return -rte_errno;
1018 : : }
1019 : :
1020 : : /* Mask for TCP src/dst ports not supported */
1021 [ # # ]: 0 : if (tcp_mask->hdr.src_port &&
1022 : : tcp_mask->hdr.src_port != UINT16_MAX)
1023 : 0 : return -rte_errno;
1024 [ # # ]: 0 : if (tcp_mask->hdr.dst_port &&
1025 : : tcp_mask->hdr.dst_port != UINT16_MAX)
1026 : 0 : return -rte_errno;
1027 : :
1028 [ # # ]: 0 : if (tcp_mask->hdr.src_port == UINT16_MAX) {
1029 : 0 : input_set |= IAVF_INSET_TCP_SRC_PORT;
1030 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT);
1031 : : }
1032 [ # # ]: 0 : if (tcp_mask->hdr.dst_port == UINT16_MAX) {
1033 : 0 : input_set |= IAVF_INSET_TCP_DST_PORT;
1034 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT);
1035 : : }
1036 : :
1037 [ # # ]: 0 : if (tun_inner) {
1038 : 0 : input_set &= ~IAVF_PROT_TCP_OUTER;
1039 : 0 : input_set |= IAVF_PROT_TCP_INNER;
1040 : : }
1041 : :
1042 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
1043 : 0 : memcpy(hdr->buffer,
1044 : 0 : &tcp_spec->hdr,
1045 : : sizeof(tcp_spec->hdr));
1046 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
1047 : 0 : memcpy(hdr->buffer,
1048 : 0 : &tcp_spec->hdr,
1049 : : sizeof(tcp_spec->hdr));
1050 : : }
1051 : :
1052 : 0 : hdrs->count = ++layer;
1053 : 0 : break;
1054 : :
1055 : 0 : case RTE_FLOW_ITEM_TYPE_SCTP:
1056 : 0 : sctp_spec = item->spec;
1057 : 0 : sctp_mask = item->mask;
1058 : :
1059 : : hdr = &hdrs->proto_hdr[layer];
1060 : :
1061 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP);
1062 : :
1063 [ # # ]: 0 : if (sctp_spec && sctp_mask) {
1064 [ # # ]: 0 : if (sctp_mask->hdr.cksum) {
1065 : 0 : rte_flow_error_set(error, EINVAL,
1066 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
1067 : : "Invalid UDP mask");
1068 : 0 : return -rte_errno;
1069 : : }
1070 : :
1071 : : /* Mask for SCTP src/dst ports not supported */
1072 [ # # ]: 0 : if (sctp_mask->hdr.src_port &&
1073 : : sctp_mask->hdr.src_port != UINT16_MAX)
1074 : 0 : return -rte_errno;
1075 [ # # ]: 0 : if (sctp_mask->hdr.dst_port &&
1076 : : sctp_mask->hdr.dst_port != UINT16_MAX)
1077 : 0 : return -rte_errno;
1078 : :
1079 [ # # ]: 0 : if (sctp_mask->hdr.src_port == UINT16_MAX) {
1080 : 0 : input_set |= IAVF_INSET_SCTP_SRC_PORT;
1081 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT);
1082 : : }
1083 [ # # ]: 0 : if (sctp_mask->hdr.dst_port == UINT16_MAX) {
1084 : 0 : input_set |= IAVF_INSET_SCTP_DST_PORT;
1085 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
1086 : : }
1087 : :
1088 [ # # ]: 0 : if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
1089 : 0 : memcpy(hdr->buffer,
1090 : 0 : &sctp_spec->hdr,
1091 : : sizeof(sctp_spec->hdr));
1092 [ # # ]: 0 : else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
1093 : 0 : memcpy(hdr->buffer,
1094 : 0 : &sctp_spec->hdr,
1095 : : sizeof(sctp_spec->hdr));
1096 : : }
1097 : :
1098 : 0 : hdrs->count = ++layer;
1099 : 0 : break;
1100 : :
1101 : 0 : case RTE_FLOW_ITEM_TYPE_GTPU:
1102 : 0 : gtp_spec = item->spec;
1103 : 0 : gtp_mask = item->mask;
1104 : :
1105 : : hdr = &hdrs->proto_hdr[layer];
1106 : :
1107 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_IP);
1108 : :
1109 [ # # ]: 0 : if (gtp_spec && gtp_mask) {
1110 : 0 : if (gtp_mask->hdr.gtp_hdr_info ||
1111 [ # # ]: 0 : gtp_mask->hdr.msg_type ||
1112 : : gtp_mask->hdr.plen) {
1113 : 0 : rte_flow_error_set(error, EINVAL,
1114 : : RTE_FLOW_ERROR_TYPE_ITEM,
1115 : : item, "Invalid GTP mask");
1116 : 0 : return -rte_errno;
1117 : : }
1118 : :
1119 [ # # ]: 0 : if (gtp_mask->hdr.teid == UINT32_MAX) {
1120 : 0 : input_set |= IAVF_INSET_GTPU_TEID;
1121 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, GTPU_IP, TEID);
1122 : : }
1123 : :
1124 : 0 : memcpy(hdr->buffer,
1125 : : gtp_spec, sizeof(*gtp_spec));
1126 : : }
1127 : :
1128 : : tun_inner = 1;
1129 : :
1130 : 0 : hdrs->count = ++layer;
1131 : 0 : break;
1132 : :
1133 : 0 : case RTE_FLOW_ITEM_TYPE_GTP_PSC:
1134 : 0 : gtp_psc_spec = item->spec;
1135 : 0 : gtp_psc_mask = item->mask;
1136 : :
1137 : : hdr = &hdrs->proto_hdr[layer];
1138 : :
1139 [ # # ]: 0 : if (!gtp_psc_spec)
1140 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
1141 [ # # ]: 0 : else if ((gtp_psc_mask->hdr.qfi) &&
1142 [ # # ]: 0 : !(gtp_psc_mask->hdr.type))
1143 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH);
1144 [ # # ]: 0 : else if (gtp_psc_spec->hdr.type == IAVF_GTPU_EH_UPLINK)
1145 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_UP);
1146 [ # # ]: 0 : else if (gtp_psc_spec->hdr.type == IAVF_GTPU_EH_DWLINK)
1147 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GTPU_EH_PDU_DWN);
1148 : :
1149 [ # # ]: 0 : if (gtp_psc_spec && gtp_psc_mask) {
1150 [ # # ]: 0 : if (gtp_psc_mask->hdr.qfi == 0x3F) {
1151 : 0 : input_set |= IAVF_INSET_GTPU_QFI;
1152 [ # # ]: 0 : if (!gtp_psc_mask->hdr.type)
1153 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
1154 : : GTPU_EH, QFI);
1155 [ # # ]: 0 : else if (gtp_psc_spec->hdr.type ==
1156 : : IAVF_GTPU_EH_UPLINK)
1157 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
1158 : : GTPU_UP, QFI);
1159 [ # # ]: 0 : else if (gtp_psc_spec->hdr.type ==
1160 : : IAVF_GTPU_EH_DWLINK)
1161 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
1162 : : GTPU_DWN, QFI);
1163 : : }
1164 : :
1165 : : /*
1166 : : * New structure to fix gap between kernel driver and
1167 : : * rte_gtp_psc_generic_hdr.
1168 : : */
1169 : : struct iavf_gtp_psc_spec_hdr {
1170 : : uint8_t len;
1171 : : uint8_t qfi:6;
1172 : : uint8_t type:4;
1173 : : uint8_t next;
1174 : : } psc;
1175 : 0 : psc.len = gtp_psc_spec->hdr.ext_hdr_len;
1176 : 0 : psc.qfi = gtp_psc_spec->hdr.qfi;
1177 : 0 : psc.type = gtp_psc_spec->hdr.type;
1178 : 0 : psc.next = 0;
1179 : 0 : memcpy(hdr->buffer, &psc,
1180 : : sizeof(struct iavf_gtp_psc_spec_hdr));
1181 : : }
1182 : :
1183 : 0 : hdrs->count = ++layer;
1184 : 0 : break;
1185 : :
1186 : 0 : case RTE_FLOW_ITEM_TYPE_L2TPV3OIP:
1187 : 0 : l2tpv3oip_spec = item->spec;
1188 : 0 : l2tpv3oip_mask = item->mask;
1189 : :
1190 : : hdr = &hdrs->proto_hdr[layer];
1191 : :
1192 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, L2TPV3);
1193 : :
1194 [ # # ]: 0 : if (l2tpv3oip_spec && l2tpv3oip_mask) {
1195 [ # # ]: 0 : if (l2tpv3oip_mask->session_id == UINT32_MAX) {
1196 : 0 : input_set |= IAVF_L2TPV3OIP_SESSION_ID;
1197 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, L2TPV3, SESS_ID);
1198 : : }
1199 : :
1200 : 0 : memcpy(hdr->buffer, l2tpv3oip_spec,
1201 : : sizeof(*l2tpv3oip_spec));
1202 : : }
1203 : :
1204 : 0 : hdrs->count = ++layer;
1205 : 0 : break;
1206 : :
1207 : 0 : case RTE_FLOW_ITEM_TYPE_ESP:
1208 : 0 : esp_spec = item->spec;
1209 : 0 : esp_mask = item->mask;
1210 : :
1211 : : hdr = &hdrs->proto_hdr[layer];
1212 : :
1213 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, ESP);
1214 : :
1215 [ # # ]: 0 : if (esp_spec && esp_mask) {
1216 [ # # ]: 0 : if (esp_mask->hdr.spi == UINT32_MAX) {
1217 : 0 : input_set |= IAVF_INSET_ESP_SPI;
1218 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, ESP, SPI);
1219 : : }
1220 : :
1221 : 0 : memcpy(hdr->buffer, &esp_spec->hdr,
1222 : : sizeof(esp_spec->hdr));
1223 : : }
1224 : :
1225 : 0 : hdrs->count = ++layer;
1226 : 0 : break;
1227 : :
1228 : 0 : case RTE_FLOW_ITEM_TYPE_AH:
1229 : 0 : ah_spec = item->spec;
1230 : 0 : ah_mask = item->mask;
1231 : :
1232 : : hdr = &hdrs->proto_hdr[layer];
1233 : :
1234 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, AH);
1235 : :
1236 [ # # ]: 0 : if (ah_spec && ah_mask) {
1237 [ # # ]: 0 : if (ah_mask->spi == UINT32_MAX) {
1238 : 0 : input_set |= IAVF_INSET_AH_SPI;
1239 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, AH, SPI);
1240 : : }
1241 : :
1242 : 0 : memcpy(hdr->buffer, ah_spec,
1243 : : sizeof(*ah_spec));
1244 : : }
1245 : :
1246 : 0 : hdrs->count = ++layer;
1247 : 0 : break;
1248 : :
1249 : 0 : case RTE_FLOW_ITEM_TYPE_PFCP:
1250 : 0 : pfcp_spec = item->spec;
1251 : 0 : pfcp_mask = item->mask;
1252 : :
1253 : : hdr = &hdrs->proto_hdr[layer];
1254 : :
1255 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, PFCP);
1256 : :
1257 [ # # ]: 0 : if (pfcp_spec && pfcp_mask) {
1258 [ # # ]: 0 : if (pfcp_mask->s_field == UINT8_MAX) {
1259 : 0 : input_set |= IAVF_INSET_PFCP_S_FIELD;
1260 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, PFCP, S_FIELD);
1261 : : }
1262 : :
1263 : 0 : memcpy(hdr->buffer, pfcp_spec,
1264 : : sizeof(*pfcp_spec));
1265 : : }
1266 : :
1267 : 0 : hdrs->count = ++layer;
1268 : 0 : break;
1269 : :
1270 : 0 : case RTE_FLOW_ITEM_TYPE_ECPRI:
1271 : 0 : ecpri_spec = item->spec;
1272 : 0 : ecpri_mask = item->mask;
1273 : :
1274 [ # # ]: 0 : ecpri_common.u32 = rte_be_to_cpu_32(ecpri_spec->hdr.common.u32);
1275 : :
1276 : : hdr = &hdrs->proto_hdr[layer];
1277 : :
1278 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, ECPRI);
1279 : :
1280 [ # # ]: 0 : if (ecpri_spec && ecpri_mask) {
1281 [ # # ]: 0 : if (ecpri_common.type == RTE_ECPRI_MSG_TYPE_IQ_DATA &&
1282 [ # # ]: 0 : ecpri_mask->hdr.type0.pc_id == UINT16_MAX) {
1283 : 0 : input_set |= IAVF_ECPRI_PC_RTC_ID;
1284 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, ECPRI,
1285 : : PC_RTC_ID);
1286 : : }
1287 : :
1288 : 0 : memcpy(hdr->buffer, ecpri_spec,
1289 : : sizeof(*ecpri_spec));
1290 : : }
1291 : :
1292 : 0 : hdrs->count = ++layer;
1293 : 0 : break;
1294 : :
1295 : 0 : case RTE_FLOW_ITEM_TYPE_GRE:
1296 : 0 : gre_spec = item->spec;
1297 : 0 : gre_mask = item->mask;
1298 : :
1299 : : hdr = &hdrs->proto_hdr[layer];
1300 : :
1301 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, GRE);
1302 : :
1303 [ # # ]: 0 : if (gre_spec && gre_mask) {
1304 : 0 : memcpy(hdr->buffer, gre_spec,
1305 : : sizeof(*gre_spec));
1306 : : }
1307 : :
1308 : : tun_inner = 1;
1309 : :
1310 : 0 : hdrs->count = ++layer;
1311 : 0 : break;
1312 : :
1313 : 0 : case RTE_FLOW_ITEM_TYPE_L2TPV2:
1314 : 0 : l2tpv2_spec = item->spec;
1315 : 0 : l2tpv2_mask = item->mask;
1316 : :
1317 : : hdr = &hdrs->proto_hdr[layer];
1318 : :
1319 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, L2TPV2);
1320 : :
1321 [ # # ]: 0 : if (l2tpv2_spec && l2tpv2_mask) {
1322 : : flags_version =
1323 [ # # ]: 0 : rte_be_to_cpu_16(l2tpv2_spec->hdr.common.flags_version);
1324 [ # # ]: 0 : if ((flags_version == RTE_L2TPV2_MSG_TYPE_CONTROL &&
1325 [ # # # # ]: 0 : l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) ||
1326 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA &&
1327 [ # # # # ]: 0 : l2tpv2_mask->hdr.type7.session_id == UINT16_MAX) ||
1328 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L &&
1329 [ # # # # ]: 0 : l2tpv2_mask->hdr.type6.session_id == UINT16_MAX) ||
1330 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S &&
1331 [ # # # # ]: 0 : l2tpv2_mask->hdr.type5.session_id == UINT16_MAX) ||
1332 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_O &&
1333 [ # # # # ]: 0 : l2tpv2_mask->hdr.type4.session_id == UINT16_MAX) ||
1334 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S &&
1335 [ # # # # ]: 0 : l2tpv2_mask->hdr.type3.session_id == UINT16_MAX) ||
1336 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_O &&
1337 [ # # # # ]: 0 : l2tpv2_mask->hdr.type2.session_id == UINT16_MAX) ||
1338 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_S_O &&
1339 [ # # # # ]: 0 : l2tpv2_mask->hdr.type1.session_id == UINT16_MAX) ||
1340 : 0 : (flags_version == RTE_L2TPV2_MSG_TYPE_DATA_L_S_O &&
1341 [ # # ]: 0 : l2tpv2_mask->hdr.type0.session_id == UINT16_MAX)) {
1342 : 0 : input_set |= IAVF_L2TPV2_SESSION_ID;
1343 [ # # ]: 0 : if (flags_version & IAVF_L2TPV2_FLAGS_LEN)
1344 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
1345 : : L2TPV2,
1346 : : LEN_SESS_ID);
1347 : : else
1348 : 0 : VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr,
1349 : : L2TPV2,
1350 : : SESS_ID);
1351 : : }
1352 : :
1353 : 0 : memcpy(hdr->buffer, l2tpv2_spec,
1354 : : sizeof(*l2tpv2_spec));
1355 : : }
1356 : :
1357 : : tun_inner = 1;
1358 : :
1359 : 0 : hdrs->count = ++layer;
1360 : 0 : break;
1361 : :
1362 : 0 : case RTE_FLOW_ITEM_TYPE_PPP:
1363 : 0 : ppp_spec = item->spec;
1364 : 0 : ppp_mask = item->mask;
1365 : :
1366 : : hdr = &hdrs->proto_hdr[layer];
1367 : :
1368 : 0 : VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, PPP);
1369 : :
1370 [ # # ]: 0 : if (ppp_spec && ppp_mask) {
1371 : 0 : memcpy(hdr->buffer, ppp_spec,
1372 : : sizeof(*ppp_spec));
1373 : : }
1374 : :
1375 : 0 : hdrs->count = ++layer;
1376 : 0 : break;
1377 : :
1378 : : case RTE_FLOW_ITEM_TYPE_VOID:
1379 : : break;
1380 : :
1381 : 0 : default:
1382 : 0 : rte_flow_error_set(error, EINVAL,
1383 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
1384 : : "Invalid pattern item.");
1385 : 0 : return -rte_errno;
1386 : : }
1387 : : }
1388 : :
1389 [ # # ]: 0 : if (layer > VIRTCHNL_MAX_NUM_PROTO_HDRS) {
1390 : 0 : rte_flow_error_set(error, EINVAL,
1391 : : RTE_FLOW_ERROR_TYPE_ITEM, item,
1392 : : "Protocol header layers exceed the maximum value");
1393 : 0 : return -rte_errno;
1394 : : }
1395 : :
1396 [ # # ]: 0 : if (!iavf_fdir_refine_input_set(input_set,
1397 : 0 : input_set_mask | IAVF_INSET_ETHERTYPE,
1398 : : filter)) {
1399 : 0 : rte_flow_error_set(error, EINVAL,
1400 : : RTE_FLOW_ERROR_TYPE_ITEM_SPEC, pattern,
1401 : : "Invalid input set");
1402 : 0 : return -rte_errno;
1403 : : }
1404 : :
1405 : 0 : filter->input_set = input_set;
1406 : :
1407 : 0 : return 0;
1408 : : }
1409 : :
1410 : : static int
1411 : 0 : iavf_fdir_action_check_qregion(struct iavf_adapter *ad,
1412 : : const struct rte_flow_action_rss *rss,
1413 : : struct rte_flow_error *error)
1414 : : {
1415 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1416 : :
1417 [ # # ]: 0 : if (rss->queue_num <= 1) {
1418 : 0 : return rte_flow_error_set(error, EINVAL,
1419 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
1420 : : "Queue region size can't be 0 or 1.");
1421 : : }
1422 : :
1423 [ # # ]: 0 : if (rss->queue[rss->queue_num - 1] >= ad->dev_data->nb_rx_queues) {
1424 : 0 : return rte_flow_error_set(error, EINVAL,
1425 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
1426 : : "Invalid queue region indexes.");
1427 : : }
1428 : :
1429 [ # # ]: 0 : if (!(rte_is_power_of_2(rss->queue_num) &&
1430 : : rss->queue_num <= IAVF_FDIR_MAX_QREGION_SIZE)) {
1431 : 0 : return rte_flow_error_set(error, EINVAL,
1432 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
1433 : : "The region size should be any of the following values:"
1434 : : "1, 2, 4, 8, 16, 32, 64, 128 as long as the total number "
1435 : : "of queues do not exceed the VSI allocation.");
1436 : : }
1437 : :
1438 [ # # ]: 0 : if (rss->queue_num > vf->max_rss_qregion) {
1439 : 0 : return rte_flow_error_set(error, EINVAL,
1440 : : RTE_FLOW_ERROR_TYPE_ACTION_CONF, rss,
1441 : : "The region size cannot be large than the supported max RSS queue region");
1442 : : }
1443 : :
1444 : : return 0;
1445 : : }
1446 : :
1447 : : static int
1448 : 0 : iavf_fdir_parse_action_check(const struct ci_flow_actions *actions,
1449 : : const struct ci_flow_actions_check_param *param,
1450 : : struct rte_flow_error *error)
1451 : : {
1452 : 0 : struct iavf_adapter *ad = param->driver_ctx;
1453 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1454 : : struct iavf_fdir_conf *filter = &vf->fdir.conf;
1455 : : uint32_t dest_num = 0, mark_num = 0;
1456 : : size_t i, number = 0;
1457 : : bool has_drop = false;
1458 : : int ret;
1459 : :
1460 [ # # ]: 0 : for (i = 0; i < actions->count; i++) {
1461 : 0 : const struct rte_flow_action *act = actions->actions[i];
1462 : : struct virtchnl_filter_action *filter_action =
1463 : : &filter->add_fltr.rule_cfg.action_set.actions[number];
1464 : :
1465 [ # # # # : 0 : switch (act->type) {
# # ]
1466 : 0 : case RTE_FLOW_ACTION_TYPE_PASSTHRU:
1467 : 0 : dest_num++;
1468 : :
1469 : 0 : filter_action->type = VIRTCHNL_ACTION_PASSTHRU;
1470 : 0 : break;
1471 : 0 : case RTE_FLOW_ACTION_TYPE_DROP:
1472 : 0 : dest_num++;
1473 : : has_drop = true;
1474 : :
1475 : 0 : filter_action->type = VIRTCHNL_ACTION_DROP;
1476 : 0 : break;
1477 : 0 : case RTE_FLOW_ACTION_TYPE_QUEUE:
1478 : : {
1479 : : const struct rte_flow_action_queue *act_q;
1480 : 0 : dest_num++;
1481 : :
1482 : 0 : act_q = act->conf;
1483 : :
1484 : 0 : filter_action->type = VIRTCHNL_ACTION_QUEUE;
1485 : :
1486 [ # # ]: 0 : if (act_q->index >= ad->dev_data->nb_rx_queues) {
1487 : 0 : return rte_flow_error_set(error, EINVAL,
1488 : : RTE_FLOW_ERROR_TYPE_ACTION, actions,
1489 : : "Invalid queue index.");
1490 : : }
1491 : 0 : filter_action->act_conf.queue.index = act_q->index;
1492 : :
1493 : 0 : break;
1494 : : }
1495 : 0 : case RTE_FLOW_ACTION_TYPE_RSS:
1496 : : {
1497 : 0 : const struct rte_flow_action_rss *rss = act->conf;
1498 : 0 : dest_num++;
1499 : :
1500 : 0 : filter_action->type = VIRTCHNL_ACTION_Q_REGION;
1501 : :
1502 : 0 : ret = iavf_fdir_action_check_qregion(ad, rss, error);
1503 [ # # ]: 0 : if (ret)
1504 : 0 : return ret;
1505 : :
1506 : 0 : filter_action->act_conf.queue.index = rss->queue[0];
1507 [ # # ]: 0 : filter_action->act_conf.queue.region = rte_fls_u32(rss->queue_num) - 1;
1508 : 0 : break;
1509 : : }
1510 : 0 : case RTE_FLOW_ACTION_TYPE_MARK:
1511 : : {
1512 : : const struct rte_flow_action_mark *mark_spec;
1513 : 0 : mark_num++;
1514 : :
1515 : 0 : filter->mark_flag = 1;
1516 : 0 : mark_spec = act->conf;
1517 : :
1518 : 0 : filter_action->type = VIRTCHNL_ACTION_MARK;
1519 : 0 : filter_action->act_conf.mark_id = mark_spec->id;
1520 : :
1521 : 0 : break;
1522 : : }
1523 : 0 : default:
1524 : : /* cannot happen */
1525 : 0 : return rte_flow_error_set(error, EINVAL,
1526 : : RTE_FLOW_ERROR_TYPE_ACTION, actions,
1527 : : "Invalid action.");
1528 : : }
1529 : 0 : filter->add_fltr.rule_cfg.action_set.count = ++number;
1530 : : }
1531 : :
1532 [ # # ]: 0 : if (dest_num > 1 || mark_num > 1 || (has_drop && mark_num > 1)) {
1533 : 0 : return rte_flow_error_set(error, EINVAL,
1534 : : RTE_FLOW_ERROR_TYPE_ACTION, actions,
1535 : : "Unsupported action combination");
1536 : : }
1537 : :
1538 : : /* Mark only is equal to mark + passthru. */
1539 [ # # ]: 0 : if (dest_num == 0) {
1540 : : struct virtchnl_filter_action *filter_action =
1541 : : &filter->add_fltr.rule_cfg.action_set.actions[number];
1542 : 0 : filter_action->type = VIRTCHNL_ACTION_PASSTHRU;
1543 : 0 : filter->add_fltr.rule_cfg.action_set.count = ++number;
1544 : : }
1545 : :
1546 : : return 0;
1547 : : }
1548 : :
1549 : : static int
1550 : 0 : iavf_fdir_parse(struct iavf_adapter *ad,
1551 : : struct iavf_pattern_match_item *array,
1552 : : uint32_t array_len,
1553 : : const struct rte_flow_item pattern[],
1554 : : const struct rte_flow_action actions[],
1555 : : const struct rte_flow_attr *attr,
1556 : : void **meta,
1557 : : struct rte_flow_error *error)
1558 : : {
1559 : 0 : struct ci_flow_actions parsed_actions = {0};
1560 : 0 : struct ci_flow_actions_check_param param = {
1561 : 0 : .allowed_types = (enum rte_flow_action_type[]){
1562 : : RTE_FLOW_ACTION_TYPE_PASSTHRU,
1563 : : RTE_FLOW_ACTION_TYPE_DROP,
1564 : : RTE_FLOW_ACTION_TYPE_QUEUE,
1565 : : RTE_FLOW_ACTION_TYPE_RSS,
1566 : : RTE_FLOW_ACTION_TYPE_MARK,
1567 : : RTE_FLOW_ACTION_TYPE_END
1568 : : },
1569 : : .max_actions = 2,
1570 : : .check = iavf_fdir_parse_action_check,
1571 : : .driver_ctx = ad,
1572 : : .rss_queues_contig = true,
1573 : : };
1574 : : struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(ad);
1575 : 0 : struct iavf_fdir_conf *filter = &vf->fdir.conf;
1576 : : struct iavf_pattern_match_item *item = NULL;
1577 : : int ret;
1578 : :
1579 : : memset(filter, 0, sizeof(*filter));
1580 : :
1581 : 0 : ret = ci_flow_check_attr(attr, NULL, error);
1582 [ # # ]: 0 : if (ret)
1583 : : return ret;
1584 : :
1585 : 0 : ret = ci_flow_check_actions(actions, ¶m, &parsed_actions, error);
1586 [ # # ]: 0 : if (ret)
1587 : : return ret;
1588 : :
1589 : 0 : item = iavf_search_pattern_match_item(pattern, array, array_len, error);
1590 [ # # ]: 0 : if (!item)
1591 : 0 : return -rte_errno;
1592 : :
1593 : 0 : ret = iavf_fdir_parse_pattern(ad, pattern, item->input_set_mask,
1594 : : error, filter);
1595 [ # # ]: 0 : if (ret)
1596 : 0 : goto error;
1597 : :
1598 [ # # ]: 0 : if (meta)
1599 : 0 : *meta = filter;
1600 : :
1601 : 0 : error:
1602 : 0 : rte_free(item);
1603 : 0 : return ret;
1604 : : }
1605 : :
1606 : : static struct iavf_flow_parser iavf_fdir_parser = {
1607 : : .engine = &iavf_fdir_engine,
1608 : : .array = iavf_fdir_pattern,
1609 : : .array_len = RTE_DIM(iavf_fdir_pattern),
1610 : : .parse_pattern_action = iavf_fdir_parse,
1611 : : };
1612 : :
1613 : 303 : RTE_INIT(iavf_fdir_engine_register)
1614 : : {
1615 : 303 : iavf_register_flow_engine(&iavf_fdir_engine);
1616 : 303 : }
|