1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3
4 #include <linux/bitfield.h>
5 #include <net/pkt_cls.h>
6
7 #include "cmsg.h"
8 #include "main.h"
9
10 void
nfp_flower_compile_meta(struct nfp_flower_meta_tci * ext,struct nfp_flower_meta_tci * msk,u8 key_type)11 nfp_flower_compile_meta(struct nfp_flower_meta_tci *ext,
12 struct nfp_flower_meta_tci *msk, u8 key_type)
13 {
14 /* Populate the metadata frame. */
15 ext->nfp_flow_key_layer = key_type;
16 ext->mask_id = ~0;
17
18 msk->nfp_flow_key_layer = key_type;
19 msk->mask_id = ~0;
20 }
21
22 void
nfp_flower_compile_tci(struct nfp_flower_meta_tci * ext,struct nfp_flower_meta_tci * msk,struct flow_rule * rule)23 nfp_flower_compile_tci(struct nfp_flower_meta_tci *ext,
24 struct nfp_flower_meta_tci *msk,
25 struct flow_rule *rule)
26 {
27 u16 msk_tci, key_tci;
28
29 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
30 struct flow_match_vlan match;
31
32 flow_rule_match_vlan(rule, &match);
33 /* Populate the tci field. */
34 key_tci = NFP_FLOWER_MASK_VLAN_PRESENT;
35 key_tci |= FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
36 match.key->vlan_priority) |
37 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
38 match.key->vlan_id);
39
40 msk_tci = NFP_FLOWER_MASK_VLAN_PRESENT;
41 msk_tci |= FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
42 match.mask->vlan_priority) |
43 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
44 match.mask->vlan_id);
45
46 ext->tci |= cpu_to_be16((key_tci & msk_tci));
47 msk->tci |= cpu_to_be16(msk_tci);
48 }
49 }
50
51 static void
nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci * ext,struct nfp_flower_meta_tci * msk,struct flow_rule * rule,u8 key_type,bool qinq_sup)52 nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *ext,
53 struct nfp_flower_meta_tci *msk,
54 struct flow_rule *rule, u8 key_type, bool qinq_sup)
55 {
56 memset(ext, 0, sizeof(struct nfp_flower_meta_tci));
57 memset(msk, 0, sizeof(struct nfp_flower_meta_tci));
58
59 nfp_flower_compile_meta(ext, msk, key_type);
60
61 if (!qinq_sup)
62 nfp_flower_compile_tci(ext, msk, rule);
63 }
64
65 void
nfp_flower_compile_ext_meta(struct nfp_flower_ext_meta * frame,u32 key_ext)66 nfp_flower_compile_ext_meta(struct nfp_flower_ext_meta *frame, u32 key_ext)
67 {
68 frame->nfp_flow_key_layer2 = cpu_to_be32(key_ext);
69 }
70
71 int
nfp_flower_compile_port(struct nfp_flower_in_port * frame,u32 cmsg_port,bool mask_version,enum nfp_flower_tun_type tun_type,struct netlink_ext_ack * extack)72 nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
73 bool mask_version, enum nfp_flower_tun_type tun_type,
74 struct netlink_ext_ack *extack)
75 {
76 if (mask_version) {
77 frame->in_port = cpu_to_be32(~0);
78 return 0;
79 }
80
81 if (tun_type) {
82 frame->in_port = cpu_to_be32(NFP_FL_PORT_TYPE_TUN | tun_type);
83 } else {
84 if (!cmsg_port) {
85 NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid ingress interface for match offload");
86 return -EOPNOTSUPP;
87 }
88 frame->in_port = cpu_to_be32(cmsg_port);
89 }
90
91 return 0;
92 }
93
94 void
nfp_flower_compile_mac(struct nfp_flower_mac_mpls * ext,struct nfp_flower_mac_mpls * msk,struct flow_rule * rule)95 nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext,
96 struct nfp_flower_mac_mpls *msk,
97 struct flow_rule *rule)
98 {
99 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
100 struct flow_match_eth_addrs match;
101 int i;
102
103 flow_rule_match_eth_addrs(rule, &match);
104 /* Populate mac frame. */
105 for (i = 0; i < ETH_ALEN; i++) {
106 ext->mac_dst[i] |= match.key->dst[i] &
107 match.mask->dst[i];
108 msk->mac_dst[i] |= match.mask->dst[i];
109 ext->mac_src[i] |= match.key->src[i] &
110 match.mask->src[i];
111 msk->mac_src[i] |= match.mask->src[i];
112 }
113 }
114 }
115
116 int
nfp_flower_compile_mpls(struct nfp_flower_mac_mpls * ext,struct nfp_flower_mac_mpls * msk,struct flow_rule * rule,struct netlink_ext_ack * extack)117 nfp_flower_compile_mpls(struct nfp_flower_mac_mpls *ext,
118 struct nfp_flower_mac_mpls *msk,
119 struct flow_rule *rule,
120 struct netlink_ext_ack *extack)
121 {
122 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
123 struct flow_match_mpls match;
124 u32 key_mpls, msk_mpls;
125
126 flow_rule_match_mpls(rule, &match);
127
128 /* Only support matching the first LSE */
129 if (match.mask->used_lses != 1) {
130 NL_SET_ERR_MSG_MOD(extack,
131 "unsupported offload: invalid LSE depth for MPLS match offload");
132 return -EOPNOTSUPP;
133 }
134
135 key_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB,
136 match.key->ls[0].mpls_label) |
137 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC,
138 match.key->ls[0].mpls_tc) |
139 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS,
140 match.key->ls[0].mpls_bos) |
141 NFP_FLOWER_MASK_MPLS_Q;
142
143 msk_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB,
144 match.mask->ls[0].mpls_label) |
145 FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC,
146 match.mask->ls[0].mpls_tc) |
147 FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS,
148 match.mask->ls[0].mpls_bos) |
149 NFP_FLOWER_MASK_MPLS_Q;
150
151 ext->mpls_lse |= cpu_to_be32((key_mpls & msk_mpls));
152 msk->mpls_lse |= cpu_to_be32(msk_mpls);
153 } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
154 /* Check for mpls ether type and set NFP_FLOWER_MASK_MPLS_Q
155 * bit, which indicates an mpls ether type but without any
156 * mpls fields.
157 */
158 struct flow_match_basic match;
159
160 flow_rule_match_basic(rule, &match);
161 if (match.key->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
162 match.key->n_proto == cpu_to_be16(ETH_P_MPLS_MC)) {
163 ext->mpls_lse |= cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
164 msk->mpls_lse |= cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
165 }
166 }
167
168 return 0;
169 }
170
171 static int
nfp_flower_compile_mac_mpls(struct nfp_flower_mac_mpls * ext,struct nfp_flower_mac_mpls * msk,struct flow_rule * rule,struct netlink_ext_ack * extack)172 nfp_flower_compile_mac_mpls(struct nfp_flower_mac_mpls *ext,
173 struct nfp_flower_mac_mpls *msk,
174 struct flow_rule *rule,
175 struct netlink_ext_ack *extack)
176 {
177 memset(ext, 0, sizeof(struct nfp_flower_mac_mpls));
178 memset(msk, 0, sizeof(struct nfp_flower_mac_mpls));
179
180 nfp_flower_compile_mac(ext, msk, rule);
181
182 return nfp_flower_compile_mpls(ext, msk, rule, extack);
183 }
184
185 void
nfp_flower_compile_tport(struct nfp_flower_tp_ports * ext,struct nfp_flower_tp_ports * msk,struct flow_rule * rule)186 nfp_flower_compile_tport(struct nfp_flower_tp_ports *ext,
187 struct nfp_flower_tp_ports *msk,
188 struct flow_rule *rule)
189 {
190 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
191 struct flow_match_ports match;
192
193 flow_rule_match_ports(rule, &match);
194 ext->port_src |= match.key->src & match.mask->src;
195 ext->port_dst |= match.key->dst & match.mask->dst;
196 msk->port_src |= match.mask->src;
197 msk->port_dst |= match.mask->dst;
198 }
199 }
200
201 static void
nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext * ext,struct nfp_flower_ip_ext * msk,struct flow_rule * rule)202 nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *ext,
203 struct nfp_flower_ip_ext *msk, struct flow_rule *rule)
204 {
205 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
206 struct flow_match_basic match;
207
208 flow_rule_match_basic(rule, &match);
209 ext->proto |= match.key->ip_proto & match.mask->ip_proto;
210 msk->proto |= match.mask->ip_proto;
211 }
212
213 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
214 struct flow_match_ip match;
215
216 flow_rule_match_ip(rule, &match);
217 ext->tos |= match.key->tos & match.mask->tos;
218 ext->ttl |= match.key->ttl & match.mask->ttl;
219 msk->tos |= match.mask->tos;
220 msk->ttl |= match.mask->ttl;
221 }
222
223 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP)) {
224 u16 tcp_flags, tcp_flags_mask;
225 struct flow_match_tcp match;
226
227 flow_rule_match_tcp(rule, &match);
228 tcp_flags = be16_to_cpu(match.key->flags);
229 tcp_flags_mask = be16_to_cpu(match.mask->flags);
230
231 if (tcp_flags & TCPHDR_FIN)
232 ext->flags |= NFP_FL_TCP_FLAG_FIN;
233 if (tcp_flags_mask & TCPHDR_FIN)
234 msk->flags |= NFP_FL_TCP_FLAG_FIN;
235
236 if (tcp_flags & TCPHDR_SYN)
237 ext->flags |= NFP_FL_TCP_FLAG_SYN;
238 if (tcp_flags_mask & TCPHDR_SYN)
239 msk->flags |= NFP_FL_TCP_FLAG_SYN;
240
241 if (tcp_flags & TCPHDR_RST)
242 ext->flags |= NFP_FL_TCP_FLAG_RST;
243 if (tcp_flags_mask & TCPHDR_RST)
244 msk->flags |= NFP_FL_TCP_FLAG_RST;
245
246 if (tcp_flags & TCPHDR_PSH)
247 ext->flags |= NFP_FL_TCP_FLAG_PSH;
248 if (tcp_flags_mask & TCPHDR_PSH)
249 msk->flags |= NFP_FL_TCP_FLAG_PSH;
250
251 if (tcp_flags & TCPHDR_URG)
252 ext->flags |= NFP_FL_TCP_FLAG_URG;
253 if (tcp_flags_mask & TCPHDR_URG)
254 msk->flags |= NFP_FL_TCP_FLAG_URG;
255 }
256
257 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
258 struct flow_match_control match;
259
260 flow_rule_match_control(rule, &match);
261 if (match.key->flags & FLOW_DIS_IS_FRAGMENT)
262 ext->flags |= NFP_FL_IP_FRAGMENTED;
263 if (match.mask->flags & FLOW_DIS_IS_FRAGMENT)
264 msk->flags |= NFP_FL_IP_FRAGMENTED;
265 if (match.key->flags & FLOW_DIS_FIRST_FRAG)
266 ext->flags |= NFP_FL_IP_FRAG_FIRST;
267 if (match.mask->flags & FLOW_DIS_FIRST_FRAG)
268 msk->flags |= NFP_FL_IP_FRAG_FIRST;
269 }
270 }
271
272 static void
nfp_flower_fill_vlan(struct flow_match_vlan * match,struct nfp_flower_vlan * ext,struct nfp_flower_vlan * msk,bool outer_vlan)273 nfp_flower_fill_vlan(struct flow_match_vlan *match,
274 struct nfp_flower_vlan *ext,
275 struct nfp_flower_vlan *msk, bool outer_vlan)
276 {
277 struct flow_dissector_key_vlan *mask = match->mask;
278 struct flow_dissector_key_vlan *key = match->key;
279 u16 msk_tci, key_tci;
280
281 key_tci = NFP_FLOWER_MASK_VLAN_PRESENT;
282 key_tci |= FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
283 key->vlan_priority) |
284 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
285 key->vlan_id);
286 msk_tci = NFP_FLOWER_MASK_VLAN_PRESENT;
287 msk_tci |= FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
288 mask->vlan_priority) |
289 FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
290 mask->vlan_id);
291
292 if (outer_vlan) {
293 ext->outer_tci |= cpu_to_be16((key_tci & msk_tci));
294 ext->outer_tpid |= key->vlan_tpid & mask->vlan_tpid;
295 msk->outer_tci |= cpu_to_be16(msk_tci);
296 msk->outer_tpid |= mask->vlan_tpid;
297 } else {
298 ext->inner_tci |= cpu_to_be16((key_tci & msk_tci));
299 ext->inner_tpid |= key->vlan_tpid & mask->vlan_tpid;
300 msk->inner_tci |= cpu_to_be16(msk_tci);
301 msk->inner_tpid |= mask->vlan_tpid;
302 }
303 }
304
305 void
nfp_flower_compile_vlan(struct nfp_flower_vlan * ext,struct nfp_flower_vlan * msk,struct flow_rule * rule)306 nfp_flower_compile_vlan(struct nfp_flower_vlan *ext,
307 struct nfp_flower_vlan *msk,
308 struct flow_rule *rule)
309 {
310 struct flow_match_vlan match;
311
312 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
313 flow_rule_match_vlan(rule, &match);
314 nfp_flower_fill_vlan(&match, ext, msk, true);
315 }
316 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN)) {
317 flow_rule_match_cvlan(rule, &match);
318 nfp_flower_fill_vlan(&match, ext, msk, false);
319 }
320 }
321
322 void
nfp_flower_compile_ipv4(struct nfp_flower_ipv4 * ext,struct nfp_flower_ipv4 * msk,struct flow_rule * rule)323 nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *ext,
324 struct nfp_flower_ipv4 *msk, struct flow_rule *rule)
325 {
326 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
327 struct flow_match_ipv4_addrs match;
328
329 flow_rule_match_ipv4_addrs(rule, &match);
330 ext->ipv4_src |= match.key->src & match.mask->src;
331 ext->ipv4_dst |= match.key->dst & match.mask->dst;
332 msk->ipv4_src |= match.mask->src;
333 msk->ipv4_dst |= match.mask->dst;
334 }
335
336 nfp_flower_compile_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
337 }
338
339 void
nfp_flower_compile_ipv6(struct nfp_flower_ipv6 * ext,struct nfp_flower_ipv6 * msk,struct flow_rule * rule)340 nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *ext,
341 struct nfp_flower_ipv6 *msk, struct flow_rule *rule)
342 {
343 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
344 struct flow_match_ipv6_addrs match;
345 int i;
346
347 flow_rule_match_ipv6_addrs(rule, &match);
348 for (i = 0; i < sizeof(ext->ipv6_src); i++) {
349 ext->ipv6_src.s6_addr[i] |= match.key->src.s6_addr[i] &
350 match.mask->src.s6_addr[i];
351 ext->ipv6_dst.s6_addr[i] |= match.key->dst.s6_addr[i] &
352 match.mask->dst.s6_addr[i];
353 msk->ipv6_src.s6_addr[i] |= match.mask->src.s6_addr[i];
354 msk->ipv6_dst.s6_addr[i] |= match.mask->dst.s6_addr[i];
355 }
356 }
357
358 nfp_flower_compile_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
359 }
360
361 void
nfp_flower_compile_geneve_opt(u8 * ext,u8 * msk,struct flow_rule * rule)362 nfp_flower_compile_geneve_opt(u8 *ext, u8 *msk, struct flow_rule *rule)
363 {
364 struct flow_match_enc_opts match;
365 int i;
366
367 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_OPTS)) {
368 flow_rule_match_enc_opts(rule, &match);
369
370 for (i = 0; i < match.mask->len; i++) {
371 ext[i] |= match.key->data[i] & match.mask->data[i];
372 msk[i] |= match.mask->data[i];
373 }
374 }
375 }
376
377 static void
nfp_flower_compile_tun_ipv4_addrs(struct nfp_flower_tun_ipv4 * ext,struct nfp_flower_tun_ipv4 * msk,struct flow_rule * rule)378 nfp_flower_compile_tun_ipv4_addrs(struct nfp_flower_tun_ipv4 *ext,
379 struct nfp_flower_tun_ipv4 *msk,
380 struct flow_rule *rule)
381 {
382 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
383 struct flow_match_ipv4_addrs match;
384
385 flow_rule_match_enc_ipv4_addrs(rule, &match);
386 ext->src |= match.key->src & match.mask->src;
387 ext->dst |= match.key->dst & match.mask->dst;
388 msk->src |= match.mask->src;
389 msk->dst |= match.mask->dst;
390 }
391 }
392
393 static void
nfp_flower_compile_tun_ipv6_addrs(struct nfp_flower_tun_ipv6 * ext,struct nfp_flower_tun_ipv6 * msk,struct flow_rule * rule)394 nfp_flower_compile_tun_ipv6_addrs(struct nfp_flower_tun_ipv6 *ext,
395 struct nfp_flower_tun_ipv6 *msk,
396 struct flow_rule *rule)
397 {
398 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
399 struct flow_match_ipv6_addrs match;
400 int i;
401
402 flow_rule_match_enc_ipv6_addrs(rule, &match);
403 for (i = 0; i < sizeof(ext->src); i++) {
404 ext->src.s6_addr[i] |= match.key->src.s6_addr[i] &
405 match.mask->src.s6_addr[i];
406 ext->dst.s6_addr[i] |= match.key->dst.s6_addr[i] &
407 match.mask->dst.s6_addr[i];
408 msk->src.s6_addr[i] |= match.mask->src.s6_addr[i];
409 msk->dst.s6_addr[i] |= match.mask->dst.s6_addr[i];
410 }
411 }
412 }
413
414 static void
nfp_flower_compile_tun_ip_ext(struct nfp_flower_tun_ip_ext * ext,struct nfp_flower_tun_ip_ext * msk,struct flow_rule * rule)415 nfp_flower_compile_tun_ip_ext(struct nfp_flower_tun_ip_ext *ext,
416 struct nfp_flower_tun_ip_ext *msk,
417 struct flow_rule *rule)
418 {
419 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) {
420 struct flow_match_ip match;
421
422 flow_rule_match_enc_ip(rule, &match);
423 ext->tos |= match.key->tos & match.mask->tos;
424 ext->ttl |= match.key->ttl & match.mask->ttl;
425 msk->tos |= match.mask->tos;
426 msk->ttl |= match.mask->ttl;
427 }
428 }
429
430 static void
nfp_flower_compile_tun_udp_key(__be32 * key,__be32 * key_msk,struct flow_rule * rule)431 nfp_flower_compile_tun_udp_key(__be32 *key, __be32 *key_msk,
432 struct flow_rule *rule)
433 {
434 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
435 struct flow_match_enc_keyid match;
436 u32 vni;
437
438 flow_rule_match_enc_keyid(rule, &match);
439 vni = be32_to_cpu((match.key->keyid & match.mask->keyid)) <<
440 NFP_FL_TUN_VNI_OFFSET;
441 *key |= cpu_to_be32(vni);
442 vni = be32_to_cpu(match.mask->keyid) << NFP_FL_TUN_VNI_OFFSET;
443 *key_msk |= cpu_to_be32(vni);
444 }
445 }
446
447 static void
nfp_flower_compile_tun_gre_key(__be32 * key,__be32 * key_msk,__be16 * flags,__be16 * flags_msk,struct flow_rule * rule)448 nfp_flower_compile_tun_gre_key(__be32 *key, __be32 *key_msk, __be16 *flags,
449 __be16 *flags_msk, struct flow_rule *rule)
450 {
451 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
452 struct flow_match_enc_keyid match;
453
454 flow_rule_match_enc_keyid(rule, &match);
455 *key |= match.key->keyid & match.mask->keyid;
456 *key_msk |= match.mask->keyid;
457
458 *flags = cpu_to_be16(NFP_FL_GRE_FLAG_KEY);
459 *flags_msk = cpu_to_be16(NFP_FL_GRE_FLAG_KEY);
460 }
461 }
462
463 void
nfp_flower_compile_ipv4_gre_tun(struct nfp_flower_ipv4_gre_tun * ext,struct nfp_flower_ipv4_gre_tun * msk,struct flow_rule * rule)464 nfp_flower_compile_ipv4_gre_tun(struct nfp_flower_ipv4_gre_tun *ext,
465 struct nfp_flower_ipv4_gre_tun *msk,
466 struct flow_rule *rule)
467 {
468 /* NVGRE is the only supported GRE tunnel type */
469 ext->ethertype = cpu_to_be16(ETH_P_TEB);
470 msk->ethertype = cpu_to_be16(~0);
471
472 nfp_flower_compile_tun_ipv4_addrs(&ext->ipv4, &msk->ipv4, rule);
473 nfp_flower_compile_tun_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
474 nfp_flower_compile_tun_gre_key(&ext->tun_key, &msk->tun_key,
475 &ext->tun_flags, &msk->tun_flags, rule);
476 }
477
478 void
nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun * ext,struct nfp_flower_ipv4_udp_tun * msk,struct flow_rule * rule)479 nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *ext,
480 struct nfp_flower_ipv4_udp_tun *msk,
481 struct flow_rule *rule)
482 {
483 nfp_flower_compile_tun_ipv4_addrs(&ext->ipv4, &msk->ipv4, rule);
484 nfp_flower_compile_tun_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
485 nfp_flower_compile_tun_udp_key(&ext->tun_id, &msk->tun_id, rule);
486 }
487
488 void
nfp_flower_compile_ipv6_udp_tun(struct nfp_flower_ipv6_udp_tun * ext,struct nfp_flower_ipv6_udp_tun * msk,struct flow_rule * rule)489 nfp_flower_compile_ipv6_udp_tun(struct nfp_flower_ipv6_udp_tun *ext,
490 struct nfp_flower_ipv6_udp_tun *msk,
491 struct flow_rule *rule)
492 {
493 nfp_flower_compile_tun_ipv6_addrs(&ext->ipv6, &msk->ipv6, rule);
494 nfp_flower_compile_tun_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
495 nfp_flower_compile_tun_udp_key(&ext->tun_id, &msk->tun_id, rule);
496 }
497
498 void
nfp_flower_compile_ipv6_gre_tun(struct nfp_flower_ipv6_gre_tun * ext,struct nfp_flower_ipv6_gre_tun * msk,struct flow_rule * rule)499 nfp_flower_compile_ipv6_gre_tun(struct nfp_flower_ipv6_gre_tun *ext,
500 struct nfp_flower_ipv6_gre_tun *msk,
501 struct flow_rule *rule)
502 {
503 /* NVGRE is the only supported GRE tunnel type */
504 ext->ethertype = cpu_to_be16(ETH_P_TEB);
505 msk->ethertype = cpu_to_be16(~0);
506
507 nfp_flower_compile_tun_ipv6_addrs(&ext->ipv6, &msk->ipv6, rule);
508 nfp_flower_compile_tun_ip_ext(&ext->ip_ext, &msk->ip_ext, rule);
509 nfp_flower_compile_tun_gre_key(&ext->tun_key, &msk->tun_key,
510 &ext->tun_flags, &msk->tun_flags, rule);
511 }
512
nfp_flower_compile_flow_match(struct nfp_app * app,struct flow_rule * rule,struct nfp_fl_key_ls * key_ls,struct net_device * netdev,struct nfp_fl_payload * nfp_flow,enum nfp_flower_tun_type tun_type,struct netlink_ext_ack * extack)513 int nfp_flower_compile_flow_match(struct nfp_app *app,
514 struct flow_rule *rule,
515 struct nfp_fl_key_ls *key_ls,
516 struct net_device *netdev,
517 struct nfp_fl_payload *nfp_flow,
518 enum nfp_flower_tun_type tun_type,
519 struct netlink_ext_ack *extack)
520 {
521 struct nfp_flower_priv *priv = app->priv;
522 bool qinq_sup;
523 u32 port_id;
524 int ext_len;
525 int err;
526 u8 *ext;
527 u8 *msk;
528
529 port_id = nfp_flower_get_port_id_from_netdev(app, netdev);
530
531 memset(nfp_flow->unmasked_data, 0, key_ls->key_size);
532 memset(nfp_flow->mask_data, 0, key_ls->key_size);
533
534 ext = nfp_flow->unmasked_data;
535 msk = nfp_flow->mask_data;
536
537 qinq_sup = !!(priv->flower_ext_feats & NFP_FL_FEATS_VLAN_QINQ);
538
539 nfp_flower_compile_meta_tci((struct nfp_flower_meta_tci *)ext,
540 (struct nfp_flower_meta_tci *)msk,
541 rule, key_ls->key_layer, qinq_sup);
542 ext += sizeof(struct nfp_flower_meta_tci);
543 msk += sizeof(struct nfp_flower_meta_tci);
544
545 /* Populate Extended Metadata if Required. */
546 if (NFP_FLOWER_LAYER_EXT_META & key_ls->key_layer) {
547 nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)ext,
548 key_ls->key_layer_two);
549 nfp_flower_compile_ext_meta((struct nfp_flower_ext_meta *)msk,
550 key_ls->key_layer_two);
551 ext += sizeof(struct nfp_flower_ext_meta);
552 msk += sizeof(struct nfp_flower_ext_meta);
553 }
554
555 /* Populate Exact Port data. */
556 err = nfp_flower_compile_port((struct nfp_flower_in_port *)ext,
557 port_id, false, tun_type, extack);
558 if (err)
559 return err;
560
561 /* Populate Mask Port Data. */
562 err = nfp_flower_compile_port((struct nfp_flower_in_port *)msk,
563 port_id, true, tun_type, extack);
564 if (err)
565 return err;
566
567 ext += sizeof(struct nfp_flower_in_port);
568 msk += sizeof(struct nfp_flower_in_port);
569
570 if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) {
571 err = nfp_flower_compile_mac_mpls((struct nfp_flower_mac_mpls *)ext,
572 (struct nfp_flower_mac_mpls *)msk,
573 rule, extack);
574 if (err)
575 return err;
576
577 ext += sizeof(struct nfp_flower_mac_mpls);
578 msk += sizeof(struct nfp_flower_mac_mpls);
579 }
580
581 if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) {
582 nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext,
583 (struct nfp_flower_tp_ports *)msk,
584 rule);
585 ext += sizeof(struct nfp_flower_tp_ports);
586 msk += sizeof(struct nfp_flower_tp_ports);
587 }
588
589 if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) {
590 nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext,
591 (struct nfp_flower_ipv4 *)msk,
592 rule);
593 ext += sizeof(struct nfp_flower_ipv4);
594 msk += sizeof(struct nfp_flower_ipv4);
595 }
596
597 if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) {
598 nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext,
599 (struct nfp_flower_ipv6 *)msk,
600 rule);
601 ext += sizeof(struct nfp_flower_ipv6);
602 msk += sizeof(struct nfp_flower_ipv6);
603 }
604
605 if (NFP_FLOWER_LAYER2_QINQ & key_ls->key_layer_two) {
606 nfp_flower_compile_vlan((struct nfp_flower_vlan *)ext,
607 (struct nfp_flower_vlan *)msk,
608 rule);
609 ext += sizeof(struct nfp_flower_vlan);
610 msk += sizeof(struct nfp_flower_vlan);
611 }
612
613 if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GRE) {
614 if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
615 struct nfp_flower_ipv6_gre_tun *gre_match;
616 struct nfp_ipv6_addr_entry *entry;
617 struct in6_addr *dst;
618
619 nfp_flower_compile_ipv6_gre_tun((void *)ext,
620 (void *)msk, rule);
621 gre_match = (struct nfp_flower_ipv6_gre_tun *)ext;
622 dst = &gre_match->ipv6.dst;
623 ext += sizeof(struct nfp_flower_ipv6_gre_tun);
624 msk += sizeof(struct nfp_flower_ipv6_gre_tun);
625
626 entry = nfp_tunnel_add_ipv6_off(app, dst);
627 if (!entry)
628 return -EOPNOTSUPP;
629
630 nfp_flow->nfp_tun_ipv6 = entry;
631 } else {
632 __be32 dst;
633
634 nfp_flower_compile_ipv4_gre_tun((void *)ext,
635 (void *)msk, rule);
636 dst = ((struct nfp_flower_ipv4_gre_tun *)ext)->ipv4.dst;
637 ext += sizeof(struct nfp_flower_ipv4_gre_tun);
638 msk += sizeof(struct nfp_flower_ipv4_gre_tun);
639
640 /* Store the tunnel destination in the rule data.
641 * This must be present and be an exact match.
642 */
643 nfp_flow->nfp_tun_ipv4_addr = dst;
644 nfp_tunnel_add_ipv4_off(app, dst);
645 }
646 }
647
648 if (key_ls->key_layer & NFP_FLOWER_LAYER_VXLAN ||
649 key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
650 if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_TUN_IPV6) {
651 struct nfp_flower_ipv6_udp_tun *udp_match;
652 struct nfp_ipv6_addr_entry *entry;
653 struct in6_addr *dst;
654
655 nfp_flower_compile_ipv6_udp_tun((void *)ext,
656 (void *)msk, rule);
657 udp_match = (struct nfp_flower_ipv6_udp_tun *)ext;
658 dst = &udp_match->ipv6.dst;
659 ext += sizeof(struct nfp_flower_ipv6_udp_tun);
660 msk += sizeof(struct nfp_flower_ipv6_udp_tun);
661
662 entry = nfp_tunnel_add_ipv6_off(app, dst);
663 if (!entry)
664 return -EOPNOTSUPP;
665
666 nfp_flow->nfp_tun_ipv6 = entry;
667 } else {
668 __be32 dst;
669
670 nfp_flower_compile_ipv4_udp_tun((void *)ext,
671 (void *)msk, rule);
672 dst = ((struct nfp_flower_ipv4_udp_tun *)ext)->ipv4.dst;
673 ext += sizeof(struct nfp_flower_ipv4_udp_tun);
674 msk += sizeof(struct nfp_flower_ipv4_udp_tun);
675
676 /* Store the tunnel destination in the rule data.
677 * This must be present and be an exact match.
678 */
679 nfp_flow->nfp_tun_ipv4_addr = dst;
680 nfp_tunnel_add_ipv4_off(app, dst);
681 }
682
683 if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) {
684 nfp_flower_compile_geneve_opt(ext, msk, rule);
685 }
686 }
687
688 /* Check that the flow key does not exceed the maximum limit.
689 * All structures in the key is multiples of 4 bytes, so use u32.
690 */
691 ext_len = (u32 *)ext - (u32 *)nfp_flow->unmasked_data;
692 if (ext_len > NFP_FLOWER_KEY_MAX_LW) {
693 NL_SET_ERR_MSG_MOD(extack,
694 "unsupported offload: flow key too long");
695 return -EOPNOTSUPP;
696 }
697
698 return 0;
699 }
700