2 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33 #include <net/flow_dissector.h>
34 #include <net/pkt_cls.h>
35 #include <net/tc_act/tc_gact.h>
36 #include <net/tc_act/tc_skbedit.h>
37 #include <linux/mlx5/fs.h>
38 #include <linux/mlx5/device.h>
39 #include <linux/rhashtable.h>
40 #include <net/switchdev.h>
41 #include <net/tc_act/tc_mirred.h>
42 #include <net/tc_act/tc_vlan.h>
43 #include <net/tc_act/tc_tunnel_key.h>
44 #include <net/vxlan.h>
50 struct mlx5e_tc_flow
{
51 struct rhash_head node
;
53 struct mlx5_flow_handle
*rule
;
54 struct list_head encap
; /* flows sharing the same encap */
55 struct mlx5_esw_flow_attr
*attr
;
59 MLX5_HEADER_TYPE_VXLAN
= 0x0,
60 MLX5_HEADER_TYPE_NVGRE
= 0x1,
63 #define MLX5E_TC_TABLE_NUM_ENTRIES 1024
64 #define MLX5E_TC_TABLE_NUM_GROUPS 4
66 static struct mlx5_flow_handle
*
67 mlx5e_tc_add_nic_flow(struct mlx5e_priv
*priv
,
68 struct mlx5_flow_spec
*spec
,
69 u32 action
, u32 flow_tag
)
71 struct mlx5_core_dev
*dev
= priv
->mdev
;
72 struct mlx5_flow_destination dest
= { 0 };
73 struct mlx5_flow_act flow_act
= {
78 struct mlx5_fc
*counter
= NULL
;
79 struct mlx5_flow_handle
*rule
;
80 bool table_created
= false;
82 if (action
& MLX5_FLOW_CONTEXT_ACTION_FWD_DEST
) {
83 dest
.type
= MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE
;
84 dest
.ft
= priv
->fs
.vlan
.ft
.t
;
85 } else if (action
& MLX5_FLOW_CONTEXT_ACTION_COUNT
) {
86 counter
= mlx5_fc_create(dev
, true);
88 return ERR_CAST(counter
);
90 dest
.type
= MLX5_FLOW_DESTINATION_TYPE_COUNTER
;
91 dest
.counter
= counter
;
94 if (IS_ERR_OR_NULL(priv
->fs
.tc
.t
)) {
96 mlx5_create_auto_grouped_flow_table(priv
->fs
.ns
,
98 MLX5E_TC_TABLE_NUM_ENTRIES
,
99 MLX5E_TC_TABLE_NUM_GROUPS
,
101 if (IS_ERR(priv
->fs
.tc
.t
)) {
102 netdev_err(priv
->netdev
,
103 "Failed to create tc offload table\n");
104 rule
= ERR_CAST(priv
->fs
.tc
.t
);
108 table_created
= true;
111 spec
->match_criteria_enable
= MLX5_MATCH_OUTER_HEADERS
;
112 rule
= mlx5_add_flow_rules(priv
->fs
.tc
.t
, spec
, &flow_act
, &dest
, 1);
121 mlx5_destroy_flow_table(priv
->fs
.tc
.t
);
122 priv
->fs
.tc
.t
= NULL
;
125 mlx5_fc_destroy(dev
, counter
);
130 static struct mlx5_flow_handle
*
131 mlx5e_tc_add_fdb_flow(struct mlx5e_priv
*priv
,
132 struct mlx5_flow_spec
*spec
,
133 struct mlx5_esw_flow_attr
*attr
)
135 struct mlx5_eswitch
*esw
= priv
->mdev
->priv
.eswitch
;
138 err
= mlx5_eswitch_add_vlan_action(esw
, attr
);
142 return mlx5_eswitch_add_offloaded_rule(esw
, spec
, attr
);
145 static void mlx5e_tc_del_flow(struct mlx5e_priv
*priv
,
146 struct mlx5_flow_handle
*rule
,
147 struct mlx5_esw_flow_attr
*attr
)
149 struct mlx5_eswitch
*esw
= priv
->mdev
->priv
.eswitch
;
150 struct mlx5_fc
*counter
= NULL
;
152 counter
= mlx5_flow_rule_counter(rule
);
154 if (esw
&& esw
->mode
== SRIOV_OFFLOADS
)
155 mlx5_eswitch_del_vlan_action(esw
, attr
);
157 mlx5_del_flow_rules(rule
);
159 mlx5_fc_destroy(priv
->mdev
, counter
);
161 if (!mlx5e_tc_num_filters(priv
) && (priv
->fs
.tc
.t
)) {
162 mlx5_destroy_flow_table(priv
->fs
.tc
.t
);
163 priv
->fs
.tc
.t
= NULL
;
167 static void parse_vxlan_attr(struct mlx5_flow_spec
*spec
,
168 struct tc_cls_flower_offload
*f
)
170 void *headers_c
= MLX5_ADDR_OF(fte_match_param
, spec
->match_criteria
,
172 void *headers_v
= MLX5_ADDR_OF(fte_match_param
, spec
->match_value
,
174 void *misc_c
= MLX5_ADDR_OF(fte_match_param
, spec
->match_criteria
,
176 void *misc_v
= MLX5_ADDR_OF(fte_match_param
, spec
->match_value
,
179 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4
, headers_c
, ip_protocol
);
180 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, ip_protocol
, IPPROTO_UDP
);
182 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_KEYID
)) {
183 struct flow_dissector_key_keyid
*key
=
184 skb_flow_dissector_target(f
->dissector
,
185 FLOW_DISSECTOR_KEY_ENC_KEYID
,
187 struct flow_dissector_key_keyid
*mask
=
188 skb_flow_dissector_target(f
->dissector
,
189 FLOW_DISSECTOR_KEY_ENC_KEYID
,
191 MLX5_SET(fte_match_set_misc
, misc_c
, vxlan_vni
,
192 be32_to_cpu(mask
->keyid
));
193 MLX5_SET(fte_match_set_misc
, misc_v
, vxlan_vni
,
194 be32_to_cpu(key
->keyid
));
198 static int parse_tunnel_attr(struct mlx5e_priv
*priv
,
199 struct mlx5_flow_spec
*spec
,
200 struct tc_cls_flower_offload
*f
)
202 void *headers_c
= MLX5_ADDR_OF(fte_match_param
, spec
->match_criteria
,
204 void *headers_v
= MLX5_ADDR_OF(fte_match_param
, spec
->match_value
,
207 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_PORTS
)) {
208 struct flow_dissector_key_ports
*key
=
209 skb_flow_dissector_target(f
->dissector
,
210 FLOW_DISSECTOR_KEY_ENC_PORTS
,
212 struct flow_dissector_key_ports
*mask
=
213 skb_flow_dissector_target(f
->dissector
,
214 FLOW_DISSECTOR_KEY_ENC_PORTS
,
217 /* Full udp dst port must be given */
218 if (memchr_inv(&mask
->dst
, 0xff, sizeof(mask
->dst
)))
221 /* udp src port isn't supported */
222 if (memchr_inv(&mask
->src
, 0, sizeof(mask
->src
)))
225 if (mlx5e_vxlan_lookup_port(priv
, be16_to_cpu(key
->dst
)) &&
226 MLX5_CAP_ESW(priv
->mdev
, vxlan_encap_decap
))
227 parse_vxlan_attr(spec
, f
);
231 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
232 udp_dport
, ntohs(mask
->dst
));
233 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
234 udp_dport
, ntohs(key
->dst
));
236 } else { /* udp dst port must be given */
240 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS
)) {
241 struct flow_dissector_key_ipv4_addrs
*key
=
242 skb_flow_dissector_target(f
->dissector
,
243 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS
,
245 struct flow_dissector_key_ipv4_addrs
*mask
=
246 skb_flow_dissector_target(f
->dissector
,
247 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS
,
249 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
250 src_ipv4_src_ipv6
.ipv4_layout
.ipv4
,
252 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
253 src_ipv4_src_ipv6
.ipv4_layout
.ipv4
,
256 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
257 dst_ipv4_dst_ipv6
.ipv4_layout
.ipv4
,
259 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
260 dst_ipv4_dst_ipv6
.ipv4_layout
.ipv4
,
264 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4
, headers_c
, ethertype
);
265 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, ethertype
, ETH_P_IP
);
267 /* Enforce DMAC when offloading incoming tunneled flows.
268 * Flow counters require a match on the DMAC.
270 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4
, headers_c
, dmac_47_16
);
271 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4
, headers_c
, dmac_15_0
);
272 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
273 dmac_47_16
), priv
->netdev
->dev_addr
);
275 /* let software handle IP fragments */
276 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, frag
, 1);
277 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, frag
, 0);
282 static int parse_cls_flower(struct mlx5e_priv
*priv
, struct mlx5_flow_spec
*spec
,
283 struct tc_cls_flower_offload
*f
)
285 void *headers_c
= MLX5_ADDR_OF(fte_match_param
, spec
->match_criteria
,
287 void *headers_v
= MLX5_ADDR_OF(fte_match_param
, spec
->match_value
,
292 if (f
->dissector
->used_keys
&
293 ~(BIT(FLOW_DISSECTOR_KEY_CONTROL
) |
294 BIT(FLOW_DISSECTOR_KEY_BASIC
) |
295 BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS
) |
296 BIT(FLOW_DISSECTOR_KEY_VLAN
) |
297 BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS
) |
298 BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS
) |
299 BIT(FLOW_DISSECTOR_KEY_PORTS
) |
300 BIT(FLOW_DISSECTOR_KEY_ENC_KEYID
) |
301 BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS
) |
302 BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS
) |
303 BIT(FLOW_DISSECTOR_KEY_ENC_PORTS
) |
304 BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL
))) {
305 netdev_warn(priv
->netdev
, "Unsupported key used: 0x%x\n",
306 f
->dissector
->used_keys
);
310 if ((dissector_uses_key(f
->dissector
,
311 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS
) ||
312 dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_KEYID
) ||
313 dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_PORTS
)) &&
314 dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ENC_CONTROL
)) {
315 struct flow_dissector_key_control
*key
=
316 skb_flow_dissector_target(f
->dissector
,
317 FLOW_DISSECTOR_KEY_ENC_CONTROL
,
319 switch (key
->addr_type
) {
320 case FLOW_DISSECTOR_KEY_IPV4_ADDRS
:
321 if (parse_tunnel_attr(priv
, spec
, f
))
328 /* In decap flow, header pointers should point to the inner
329 * headers, outer header were already set by parse_tunnel_attr
331 headers_c
= MLX5_ADDR_OF(fte_match_param
, spec
->match_criteria
,
333 headers_v
= MLX5_ADDR_OF(fte_match_param
, spec
->match_value
,
337 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_CONTROL
)) {
338 struct flow_dissector_key_control
*key
=
339 skb_flow_dissector_target(f
->dissector
,
340 FLOW_DISSECTOR_KEY_CONTROL
,
342 addr_type
= key
->addr_type
;
345 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_BASIC
)) {
346 struct flow_dissector_key_basic
*key
=
347 skb_flow_dissector_target(f
->dissector
,
348 FLOW_DISSECTOR_KEY_BASIC
,
350 struct flow_dissector_key_basic
*mask
=
351 skb_flow_dissector_target(f
->dissector
,
352 FLOW_DISSECTOR_KEY_BASIC
,
354 ip_proto
= key
->ip_proto
;
356 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, ethertype
,
357 ntohs(mask
->n_proto
));
358 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, ethertype
,
359 ntohs(key
->n_proto
));
361 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, ip_protocol
,
363 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, ip_protocol
,
367 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_ETH_ADDRS
)) {
368 struct flow_dissector_key_eth_addrs
*key
=
369 skb_flow_dissector_target(f
->dissector
,
370 FLOW_DISSECTOR_KEY_ETH_ADDRS
,
372 struct flow_dissector_key_eth_addrs
*mask
=
373 skb_flow_dissector_target(f
->dissector
,
374 FLOW_DISSECTOR_KEY_ETH_ADDRS
,
377 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
380 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
384 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
387 ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
392 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_VLAN
)) {
393 struct flow_dissector_key_vlan
*key
=
394 skb_flow_dissector_target(f
->dissector
,
395 FLOW_DISSECTOR_KEY_VLAN
,
397 struct flow_dissector_key_vlan
*mask
=
398 skb_flow_dissector_target(f
->dissector
,
399 FLOW_DISSECTOR_KEY_VLAN
,
401 if (mask
->vlan_id
|| mask
->vlan_priority
) {
402 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, vlan_tag
, 1);
403 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, vlan_tag
, 1);
405 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, first_vid
, mask
->vlan_id
);
406 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, first_vid
, key
->vlan_id
);
408 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
, first_prio
, mask
->vlan_priority
);
409 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
, first_prio
, key
->vlan_priority
);
413 if (addr_type
== FLOW_DISSECTOR_KEY_IPV4_ADDRS
) {
414 struct flow_dissector_key_ipv4_addrs
*key
=
415 skb_flow_dissector_target(f
->dissector
,
416 FLOW_DISSECTOR_KEY_IPV4_ADDRS
,
418 struct flow_dissector_key_ipv4_addrs
*mask
=
419 skb_flow_dissector_target(f
->dissector
,
420 FLOW_DISSECTOR_KEY_IPV4_ADDRS
,
423 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
424 src_ipv4_src_ipv6
.ipv4_layout
.ipv4
),
425 &mask
->src
, sizeof(mask
->src
));
426 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
427 src_ipv4_src_ipv6
.ipv4_layout
.ipv4
),
428 &key
->src
, sizeof(key
->src
));
429 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
430 dst_ipv4_dst_ipv6
.ipv4_layout
.ipv4
),
431 &mask
->dst
, sizeof(mask
->dst
));
432 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
433 dst_ipv4_dst_ipv6
.ipv4_layout
.ipv4
),
434 &key
->dst
, sizeof(key
->dst
));
437 if (addr_type
== FLOW_DISSECTOR_KEY_IPV6_ADDRS
) {
438 struct flow_dissector_key_ipv6_addrs
*key
=
439 skb_flow_dissector_target(f
->dissector
,
440 FLOW_DISSECTOR_KEY_IPV6_ADDRS
,
442 struct flow_dissector_key_ipv6_addrs
*mask
=
443 skb_flow_dissector_target(f
->dissector
,
444 FLOW_DISSECTOR_KEY_IPV6_ADDRS
,
447 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
448 src_ipv4_src_ipv6
.ipv6_layout
.ipv6
),
449 &mask
->src
, sizeof(mask
->src
));
450 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
451 src_ipv4_src_ipv6
.ipv6_layout
.ipv6
),
452 &key
->src
, sizeof(key
->src
));
454 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_c
,
455 dst_ipv4_dst_ipv6
.ipv6_layout
.ipv6
),
456 &mask
->dst
, sizeof(mask
->dst
));
457 memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4
, headers_v
,
458 dst_ipv4_dst_ipv6
.ipv6_layout
.ipv6
),
459 &key
->dst
, sizeof(key
->dst
));
462 if (dissector_uses_key(f
->dissector
, FLOW_DISSECTOR_KEY_PORTS
)) {
463 struct flow_dissector_key_ports
*key
=
464 skb_flow_dissector_target(f
->dissector
,
465 FLOW_DISSECTOR_KEY_PORTS
,
467 struct flow_dissector_key_ports
*mask
=
468 skb_flow_dissector_target(f
->dissector
,
469 FLOW_DISSECTOR_KEY_PORTS
,
473 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
474 tcp_sport
, ntohs(mask
->src
));
475 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
476 tcp_sport
, ntohs(key
->src
));
478 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
479 tcp_dport
, ntohs(mask
->dst
));
480 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
481 tcp_dport
, ntohs(key
->dst
));
485 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
486 udp_sport
, ntohs(mask
->src
));
487 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
488 udp_sport
, ntohs(key
->src
));
490 MLX5_SET(fte_match_set_lyr_2_4
, headers_c
,
491 udp_dport
, ntohs(mask
->dst
));
492 MLX5_SET(fte_match_set_lyr_2_4
, headers_v
,
493 udp_dport
, ntohs(key
->dst
));
496 netdev_err(priv
->netdev
,
497 "Only UDP and TCP transport are supported\n");
505 static int parse_tc_nic_actions(struct mlx5e_priv
*priv
, struct tcf_exts
*exts
,
506 u32
*action
, u32
*flow_tag
)
508 const struct tc_action
*a
;
511 if (tc_no_actions(exts
))
514 *flow_tag
= MLX5_FS_DEFAULT_FLOW_TAG
;
517 tcf_exts_to_list(exts
, &actions
);
518 list_for_each_entry(a
, &actions
, list
) {
519 /* Only support a single action per rule */
523 if (is_tcf_gact_shot(a
)) {
524 *action
|= MLX5_FLOW_CONTEXT_ACTION_DROP
;
525 if (MLX5_CAP_FLOWTABLE(priv
->mdev
,
526 flow_table_properties_nic_receive
.flow_counter
))
527 *action
|= MLX5_FLOW_CONTEXT_ACTION_COUNT
;
531 if (is_tcf_skbedit_mark(a
)) {
532 u32 mark
= tcf_skbedit_mark(a
);
534 if (mark
& ~MLX5E_TC_FLOW_ID_MASK
) {
535 netdev_warn(priv
->netdev
, "Bad flow mark - only 16 bit is supported: 0x%x\n",
541 *action
|= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST
;
551 static inline int cmp_encap_info(struct mlx5_encap_info
*a
,
552 struct mlx5_encap_info
*b
)
554 return memcmp(a
, b
, sizeof(*a
));
557 static inline int hash_encap_info(struct mlx5_encap_info
*info
)
559 return jhash(info
, sizeof(*info
), 0);
562 static int mlx5e_route_lookup_ipv4(struct mlx5e_priv
*priv
,
563 struct net_device
*mirred_dev
,
564 struct net_device
**out_dev
,
566 struct neighbour
**out_n
,
571 struct neighbour
*n
= NULL
;
574 #if IS_ENABLED(CONFIG_INET)
575 rt
= ip_route_output_key(dev_net(mirred_dev
), fl4
);
577 pr_warn("%s: no route to %pI4\n", __func__
, &fl4
->daddr
);
584 if (!switchdev_port_same_parent_id(priv
->netdev
, rt
->dst
.dev
)) {
585 pr_warn("%s: Can't offload the flow, netdevices aren't on the same HW e-switch\n",
591 ttl
= ip4_dst_hoplimit(&rt
->dst
);
592 n
= dst_neigh_lookup(&rt
->dst
, &fl4
->daddr
);
600 *out_dev
= rt
->dst
.dev
;
605 static int gen_vxlan_header_ipv4(struct net_device
*out_dev
,
607 unsigned char h_dest
[ETH_ALEN
],
614 int encap_size
= VXLAN_HLEN
+ sizeof(struct iphdr
) + ETH_HLEN
;
615 struct ethhdr
*eth
= (struct ethhdr
*)buf
;
616 struct iphdr
*ip
= (struct iphdr
*)((char *)eth
+ sizeof(struct ethhdr
));
617 struct udphdr
*udp
= (struct udphdr
*)((char *)ip
+ sizeof(struct iphdr
));
618 struct vxlanhdr
*vxh
= (struct vxlanhdr
*)((char *)udp
+ sizeof(struct udphdr
));
620 memset(buf
, 0, encap_size
);
622 ether_addr_copy(eth
->h_dest
, h_dest
);
623 ether_addr_copy(eth
->h_source
, out_dev
->dev_addr
);
624 eth
->h_proto
= htons(ETH_P_IP
);
630 ip
->protocol
= IPPROTO_UDP
;
634 udp
->dest
= udp_dst_port
;
635 vxh
->vx_flags
= VXLAN_HF_VNI
;
636 vxh
->vx_vni
= vxlan_vni_field(vx_vni
);
641 static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv
*priv
,
642 struct net_device
*mirred_dev
,
643 struct mlx5_encap_entry
*e
,
644 struct net_device
**out_dev
)
646 int max_encap_size
= MLX5_CAP_ESW(priv
->mdev
, max_encap_header_size
);
647 struct flowi4 fl4
= {};
655 encap_header
= kzalloc(max_encap_size
, GFP_KERNEL
);
659 switch (e
->tunnel_type
) {
660 case MLX5_HEADER_TYPE_VXLAN
:
661 fl4
.flowi4_proto
= IPPROTO_UDP
;
662 fl4
.fl4_dport
= e
->tun_info
.tp_dst
;
668 fl4
.daddr
= e
->tun_info
.daddr
;
670 err
= mlx5e_route_lookup_ipv4(priv
, mirred_dev
, out_dev
,
671 &fl4
, &n
, &saddr
, &ttl
);
676 e
->out_dev
= *out_dev
;
678 if (!(n
->nud_state
& NUD_VALID
)) {
683 neigh_ha_snapshot(e
->h_dest
, n
, *out_dev
);
685 switch (e
->tunnel_type
) {
686 case MLX5_HEADER_TYPE_VXLAN
:
687 encap_size
= gen_vxlan_header_ipv4(*out_dev
, encap_header
,
690 saddr
, e
->tun_info
.tp_dst
,
698 err
= mlx5_encap_alloc(priv
->mdev
, e
->tunnel_type
,
699 encap_size
, encap_header
, &e
->encap_id
);
705 static int mlx5e_attach_encap(struct mlx5e_priv
*priv
,
706 struct ip_tunnel_info
*tun_info
,
707 struct net_device
*mirred_dev
,
708 struct mlx5_esw_flow_attr
*attr
)
710 struct mlx5_eswitch
*esw
= priv
->mdev
->priv
.eswitch
;
711 unsigned short family
= ip_tunnel_info_af(tun_info
);
712 struct ip_tunnel_key
*key
= &tun_info
->key
;
713 struct mlx5_encap_info info
;
714 struct mlx5_encap_entry
*e
;
715 struct net_device
*out_dev
;
721 /* udp dst port must be given */
722 if (!memchr_inv(&key
->tp_dst
, 0, sizeof(key
->tp_dst
)))
725 if (mlx5e_vxlan_lookup_port(priv
, be16_to_cpu(key
->tp_dst
)) &&
726 MLX5_CAP_ESW(priv
->mdev
, vxlan_encap_decap
)) {
727 info
.tp_dst
= key
->tp_dst
;
728 info
.tun_id
= tunnel_id_to_key32(key
->tun_id
);
729 tunnel_type
= MLX5_HEADER_TYPE_VXLAN
;
736 info
.daddr
= key
->u
.ipv4
.dst
;
742 hash_key
= hash_encap_info(&info
);
744 hash_for_each_possible_rcu(esw
->offloads
.encap_tbl
, e
,
745 encap_hlist
, hash_key
) {
746 if (!cmp_encap_info(&e
->tun_info
, &info
)) {
757 e
= kzalloc(sizeof(*e
), GFP_KERNEL
);
762 e
->tunnel_type
= tunnel_type
;
763 INIT_LIST_HEAD(&e
->flows
);
765 err
= mlx5e_create_encap_header_ipv4(priv
, mirred_dev
, e
, &out_dev
);
770 hash_add_rcu(esw
->offloads
.encap_tbl
, &e
->encap_hlist
, hash_key
);
779 static int parse_tc_fdb_actions(struct mlx5e_priv
*priv
, struct tcf_exts
*exts
,
780 struct mlx5e_tc_flow
*flow
)
782 struct mlx5_esw_flow_attr
*attr
= flow
->attr
;
783 struct ip_tunnel_info
*info
= NULL
;
784 const struct tc_action
*a
;
789 if (tc_no_actions(exts
))
792 memset(attr
, 0, sizeof(*attr
));
793 attr
->in_rep
= priv
->ppriv
;
795 tcf_exts_to_list(exts
, &actions
);
796 list_for_each_entry(a
, &actions
, list
) {
797 if (is_tcf_gact_shot(a
)) {
798 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_DROP
|
799 MLX5_FLOW_CONTEXT_ACTION_COUNT
;
803 if (is_tcf_mirred_egress_redirect(a
)) {
804 int ifindex
= tcf_mirred_ifindex(a
);
805 struct net_device
*out_dev
;
806 struct mlx5e_priv
*out_priv
;
808 out_dev
= __dev_get_by_index(dev_net(priv
->netdev
), ifindex
);
810 if (switchdev_port_same_parent_id(priv
->netdev
,
812 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST
|
813 MLX5_FLOW_CONTEXT_ACTION_COUNT
;
814 out_priv
= netdev_priv(out_dev
);
815 attr
->out_rep
= out_priv
->ppriv
;
817 err
= mlx5e_attach_encap(priv
, info
,
821 list_add(&flow
->encap
, &attr
->encap
->flows
);
822 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_ENCAP
|
823 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST
|
824 MLX5_FLOW_CONTEXT_ACTION_COUNT
;
825 out_priv
= netdev_priv(attr
->encap
->out_dev
);
826 attr
->out_rep
= out_priv
->ppriv
;
828 pr_err("devices %s %s not on same switch HW, can't offload forwarding\n",
829 priv
->netdev
->name
, out_dev
->name
);
835 if (is_tcf_tunnel_set(a
)) {
836 info
= tcf_tunnel_info(a
);
844 if (is_tcf_vlan(a
)) {
845 if (tcf_vlan_action(a
) == VLAN_F_POP
) {
846 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP
;
847 } else if (tcf_vlan_action(a
) == VLAN_F_PUSH
) {
848 if (tcf_vlan_push_proto(a
) != htons(ETH_P_8021Q
))
851 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH
;
852 attr
->vlan
= tcf_vlan_push_vid(a
);
857 if (is_tcf_tunnel_release(a
)) {
858 attr
->action
|= MLX5_FLOW_CONTEXT_ACTION_DECAP
;
867 int mlx5e_configure_flower(struct mlx5e_priv
*priv
, __be16 protocol
,
868 struct tc_cls_flower_offload
*f
)
870 struct mlx5e_tc_table
*tc
= &priv
->fs
.tc
;
872 bool fdb_flow
= false;
873 u32 flow_tag
, action
;
874 struct mlx5e_tc_flow
*flow
;
875 struct mlx5_flow_spec
*spec
;
876 struct mlx5_flow_handle
*old
= NULL
;
877 struct mlx5_esw_flow_attr
*old_attr
= NULL
;
878 struct mlx5_eswitch
*esw
= priv
->mdev
->priv
.eswitch
;
880 if (esw
&& esw
->mode
== SRIOV_OFFLOADS
)
883 flow
= rhashtable_lookup_fast(&tc
->ht
, &f
->cookie
,
887 old_attr
= flow
->attr
;
890 flow
= kzalloc(sizeof(*flow
) + sizeof(struct mlx5_esw_flow_attr
),
893 flow
= kzalloc(sizeof(*flow
), GFP_KERNEL
);
896 spec
= mlx5_vzalloc(sizeof(*spec
));
897 if (!spec
|| !flow
) {
902 flow
->cookie
= f
->cookie
;
904 err
= parse_cls_flower(priv
, spec
, f
);
909 flow
->attr
= (struct mlx5_esw_flow_attr
*)(flow
+ 1);
910 err
= parse_tc_fdb_actions(priv
, f
->exts
, flow
);
913 flow
->rule
= mlx5e_tc_add_fdb_flow(priv
, spec
, flow
->attr
);
915 err
= parse_tc_nic_actions(priv
, f
->exts
, &action
, &flow_tag
);
918 flow
->rule
= mlx5e_tc_add_nic_flow(priv
, spec
, action
, flow_tag
);
921 if (IS_ERR(flow
->rule
)) {
922 err
= PTR_ERR(flow
->rule
);
926 err
= rhashtable_insert_fast(&tc
->ht
, &flow
->node
,
932 mlx5e_tc_del_flow(priv
, old
, old_attr
);
937 mlx5_del_flow_rules(flow
->rule
);
947 static void mlx5e_detach_encap(struct mlx5e_priv
*priv
,
948 struct mlx5e_tc_flow
*flow
) {
949 struct list_head
*next
= flow
->encap
.next
;
951 list_del(&flow
->encap
);
952 if (list_empty(next
)) {
953 struct mlx5_encap_entry
*e
;
955 e
= list_entry(next
, struct mlx5_encap_entry
, flows
);
957 mlx5_encap_dealloc(priv
->mdev
, e
->encap_id
);
960 hlist_del_rcu(&e
->encap_hlist
);
965 int mlx5e_delete_flower(struct mlx5e_priv
*priv
,
966 struct tc_cls_flower_offload
*f
)
968 struct mlx5e_tc_flow
*flow
;
969 struct mlx5e_tc_table
*tc
= &priv
->fs
.tc
;
971 flow
= rhashtable_lookup_fast(&tc
->ht
, &f
->cookie
,
976 rhashtable_remove_fast(&tc
->ht
, &flow
->node
, tc
->ht_params
);
978 mlx5e_tc_del_flow(priv
, flow
->rule
, flow
->attr
);
980 if (flow
->attr
->action
& MLX5_FLOW_CONTEXT_ACTION_ENCAP
)
981 mlx5e_detach_encap(priv
, flow
);
988 int mlx5e_stats_flower(struct mlx5e_priv
*priv
,
989 struct tc_cls_flower_offload
*f
)
991 struct mlx5e_tc_table
*tc
= &priv
->fs
.tc
;
992 struct mlx5e_tc_flow
*flow
;
994 struct mlx5_fc
*counter
;
1000 flow
= rhashtable_lookup_fast(&tc
->ht
, &f
->cookie
,
1005 counter
= mlx5_flow_rule_counter(flow
->rule
);
1009 mlx5_fc_query_cached(counter
, &bytes
, &packets
, &lastuse
);
1011 tcf_exts_to_list(f
->exts
, &actions
);
1012 list_for_each_entry(a
, &actions
, list
)
1013 tcf_action_stats_update(a
, bytes
, packets
, lastuse
);
1018 static const struct rhashtable_params mlx5e_tc_flow_ht_params
= {
1019 .head_offset
= offsetof(struct mlx5e_tc_flow
, node
),
1020 .key_offset
= offsetof(struct mlx5e_tc_flow
, cookie
),
1021 .key_len
= sizeof(((struct mlx5e_tc_flow
*)0)->cookie
),
1022 .automatic_shrinking
= true,
1025 int mlx5e_tc_init(struct mlx5e_priv
*priv
)
1027 struct mlx5e_tc_table
*tc
= &priv
->fs
.tc
;
1029 tc
->ht_params
= mlx5e_tc_flow_ht_params
;
1030 return rhashtable_init(&tc
->ht
, &tc
->ht_params
);
1033 static void _mlx5e_tc_del_flow(void *ptr
, void *arg
)
1035 struct mlx5e_tc_flow
*flow
= ptr
;
1036 struct mlx5e_priv
*priv
= arg
;
1038 mlx5e_tc_del_flow(priv
, flow
->rule
, flow
->attr
);
1042 void mlx5e_tc_cleanup(struct mlx5e_priv
*priv
)
1044 struct mlx5e_tc_table
*tc
= &priv
->fs
.tc
;
1046 rhashtable_free_and_destroy(&tc
->ht
, _mlx5e_tc_del_flow
, priv
);
1048 if (!IS_ERR_OR_NULL(tc
->t
)) {
1049 mlx5_destroy_flow_table(tc
->t
);