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