linux/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

/*
 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <net/flow_dissector.h>
#include <net/flow_offload.h>
#include <net/sch_generic.h>
#include <net/pkt_cls.h>
#include <linux/mlx5/fs.h>
#include <linux/mlx5/device.h>
#include <linux/rhashtable.h>
#include <linux/refcount.h>
#include <linux/completion.h>
#include <net/arp.h>
#include <net/ipv6_stubs.h>
#include <net/bareudp.h>
#include <net/bonding.h>
#include <net/dst_metadata.h>
#include "devlink.h"
#include "en.h"
#include "en/tc/post_act.h"
#include "en/tc/act_stats.h"
#include "en_rep.h"
#include "en/rep/tc.h"
#include "en/rep/neigh.h"
#include "en_tc.h"
#include "eswitch.h"
#include "fs_core.h"
#include "en/port.h"
#include "en/tc_tun.h"
#include "en/mapping.h"
#include "en/tc_ct.h"
#include "en/mod_hdr.h"
#include "en/tc_tun_encap.h"
#include "en/tc/sample.h"
#include "en/tc/act/act.h"
#include "en/tc/post_meter.h"
#include "lib/devcom.h"
#include "lib/geneve.h"
#include "lib/fs_chains.h"
#include "diag/en_tc_tracepoint.h"
#include <asm/div64.h>
#include "lag/lag.h"
#include "lag/mp.h"

#define MLX5E_TC_TABLE_NUM_GROUPS
#define MLX5E_TC_TABLE_MAX_GROUP_SIZE

struct mlx5e_tc_table {};

struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] =;

struct mlx5e_tc_jump_state {};

struct mlx5e_tc_table *mlx5e_tc_table_alloc(void)
{}

void mlx5e_tc_table_free(struct mlx5e_tc_table *tc)
{}

struct mlx5_fs_chains *mlx5e_nic_chains(struct mlx5e_tc_table *tc)
{}

/* To avoid false lock dependency warning set the tc_ht lock
 * class different than the lock class of the ht being used when deleting
 * last flow from a group and then deleting a group, we get into del_sw_flow_group()
 * which call rhashtable_destroy on fg->ftes_hash which will take ht->mutex but
 * it's different than the ht->mutex here.
 */
static struct lock_class_key tc_ht_lock_key;
static struct lock_class_key tc_ht_wq_key;

static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow);
static void free_flow_post_acts(struct mlx5e_tc_flow *flow);
static void mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow,
					struct mlx5_flow_attr *attr);

void
mlx5e_tc_match_to_reg_match(struct mlx5_flow_spec *spec,
			    enum mlx5e_tc_attr_to_reg type,
			    u32 val,
			    u32 mask)
{}

void
mlx5e_tc_match_to_reg_get_match(struct mlx5_flow_spec *spec,
				enum mlx5e_tc_attr_to_reg type,
				u32 *val,
				u32 *mask)
{}

int
mlx5e_tc_match_to_reg_set_and_get_id(struct mlx5_core_dev *mdev,
				     struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts,
				     enum mlx5_flow_namespace_type ns,
				     enum mlx5e_tc_attr_to_reg type,
				     u32 data)
{}

static struct mlx5e_tc_act_stats_handle  *
get_act_stats_handle(struct mlx5e_priv *priv)
{}

struct mlx5e_tc_int_port_priv *
mlx5e_get_int_port_priv(struct mlx5e_priv *priv)
{}

struct mlx5e_flow_meters *
mlx5e_get_flow_meters(struct mlx5_core_dev *dev)
{}

static struct mlx5_tc_ct_priv *
get_ct_priv(struct mlx5e_priv *priv)
{}

static struct mlx5e_tc_psample *
get_sample_priv(struct mlx5e_priv *priv)
{}

static struct mlx5e_post_act *
get_post_action(struct mlx5e_priv *priv)
{}

struct mlx5_flow_handle *
mlx5_tc_rule_insert(struct mlx5e_priv *priv,
		    struct mlx5_flow_spec *spec,
		    struct mlx5_flow_attr *attr)
{}

void
mlx5_tc_rule_delete(struct mlx5e_priv *priv,
		    struct mlx5_flow_handle *rule,
		    struct mlx5_flow_attr *attr)
{}

static bool
is_flow_meter_action(struct mlx5_flow_attr *attr)
{}

static int
mlx5e_tc_add_flow_meter(struct mlx5e_priv *priv,
			struct mlx5_flow_attr *attr)
{}

static void
mlx5e_tc_del_flow_meter(struct mlx5_eswitch *esw, struct mlx5_flow_attr *attr)
{}

struct mlx5_flow_handle *
mlx5e_tc_rule_offload(struct mlx5e_priv *priv,
		      struct mlx5_flow_spec *spec,
		      struct mlx5_flow_attr *attr)
{}

void
mlx5e_tc_rule_unoffload(struct mlx5e_priv *priv,
			struct mlx5_flow_handle *rule,
			struct mlx5_flow_attr *attr)
{}

int
mlx5e_tc_match_to_reg_set(struct mlx5_core_dev *mdev,
			  struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts,
			  enum mlx5_flow_namespace_type ns,
			  enum mlx5e_tc_attr_to_reg type,
			  u32 data)
{}

void mlx5e_tc_match_to_reg_mod_hdr_change(struct mlx5_core_dev *mdev,
					  struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts,
					  enum mlx5e_tc_attr_to_reg type,
					  int act_id, u32 data)
{}

struct mlx5e_hairpin {};

struct mlx5e_hairpin_entry {};

static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
			      struct mlx5e_tc_flow *flow);

struct mlx5e_tc_flow *mlx5e_flow_get(struct mlx5e_tc_flow *flow)
{}

void mlx5e_flow_put(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow)
{}

bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow)
{}

bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow)
{}

bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow)
{}

int mlx5e_get_flow_namespace(struct mlx5e_tc_flow *flow)
{}

static struct mlx5_core_dev *
get_flow_counter_dev(struct mlx5e_tc_flow *flow)
{}

static struct mod_hdr_tbl *
get_mod_hdr_table(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow)
{}

int mlx5e_tc_attach_mod_hdr(struct mlx5e_priv *priv,
			    struct mlx5e_tc_flow *flow,
			    struct mlx5_flow_attr *attr)
{}

void mlx5e_tc_detach_mod_hdr(struct mlx5e_priv *priv,
			     struct mlx5e_tc_flow *flow,
			     struct mlx5_flow_attr *attr)
{}

static
struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex)
{}

static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp)
{}

static void mlx5e_hairpin_destroy_transport(struct mlx5e_hairpin *hp)
{}

static int mlx5e_hairpin_create_indirect_rqt(struct mlx5e_hairpin *hp)
{}

static int mlx5e_hairpin_create_indirect_tirs(struct mlx5e_hairpin *hp)
{}

static void mlx5e_hairpin_destroy_indirect_tirs(struct mlx5e_hairpin *hp)
{}

static void mlx5e_hairpin_set_ttc_params(struct mlx5e_hairpin *hp,
					 struct ttc_params *ttc_params)
{}

static int mlx5e_hairpin_rss_init(struct mlx5e_hairpin *hp)
{}

static void mlx5e_hairpin_rss_cleanup(struct mlx5e_hairpin *hp)
{}

static struct mlx5e_hairpin *
mlx5e_hairpin_create(struct mlx5e_priv *priv, struct mlx5_hairpin_params *params,
		     int peer_ifindex)
{}

static void mlx5e_hairpin_destroy(struct mlx5e_hairpin *hp)
{}

static inline u32 hash_hairpin_info(u16 peer_vhca_id, u8 prio)
{}

static struct mlx5e_hairpin_entry *mlx5e_hairpin_get(struct mlx5e_priv *priv,
						     u16 peer_vhca_id, u8 prio)
{}

static void mlx5e_hairpin_put(struct mlx5e_priv *priv,
			      struct mlx5e_hairpin_entry *hpe)
{}

#define UNKNOWN_MATCH_PRIO

static int mlx5e_hairpin_get_prio(struct mlx5e_priv *priv,
				  struct mlx5_flow_spec *spec, u8 *match_prio,
				  struct netlink_ext_ack *extack)
{}

static int debugfs_hairpin_num_active_get(void *data, u64 *val)
{}
DEFINE_DEBUGFS_ATTRIBUTE();

static int debugfs_hairpin_table_dump_show(struct seq_file *file, void *priv)

{}
DEFINE_SHOW_ATTRIBUTE();

static void mlx5e_tc_debugfs_init(struct mlx5e_tc_table *tc,
				  struct dentry *dfs_root)
{}

static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv,
				  struct mlx5e_tc_flow *flow,
				  struct mlx5e_tc_flow_parse_attr *parse_attr,
				  struct netlink_ext_ack *extack)
{}

static void mlx5e_hairpin_flow_del(struct mlx5e_priv *priv,
				   struct mlx5e_tc_flow *flow)
{}

struct mlx5_flow_handle *
mlx5e_add_offloaded_nic_rule(struct mlx5e_priv *priv,
			     struct mlx5_flow_spec *spec,
			     struct mlx5_flow_attr *attr)
{}

static int
alloc_flow_attr_counter(struct mlx5_core_dev *counter_dev,
			struct mlx5_flow_attr *attr)

{}

static int
mlx5e_tc_add_nic_flow(struct mlx5e_priv *priv,
		      struct mlx5e_tc_flow *flow,
		      struct netlink_ext_ack *extack)
{}

void mlx5e_del_offloaded_nic_rule(struct mlx5e_priv *priv,
				  struct mlx5_flow_handle *rule,
				  struct mlx5_flow_attr *attr)
{}

static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
				  struct mlx5e_tc_flow *flow)
{}

struct mlx5_flow_handle *
mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
			   struct mlx5e_tc_flow *flow,
			   struct mlx5_flow_spec *spec,
			   struct mlx5_flow_attr *attr)
{}

void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
				  struct mlx5e_tc_flow *flow,
				  struct mlx5_flow_attr *attr)
{}

struct mlx5_flow_handle *
mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
			      struct mlx5e_tc_flow *flow,
			      struct mlx5_flow_spec *spec)
{}

void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
				       struct mlx5e_tc_flow *flow)
{}

/* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this
 * function.
 */
static void unready_flow_add(struct mlx5e_tc_flow *flow,
			     struct list_head *unready_flows)
{}

/* Caller must obtain uplink_priv->unready_flows_lock mutex before calling this
 * function.
 */
static void unready_flow_del(struct mlx5e_tc_flow *flow)
{}

static void add_unready_flow(struct mlx5e_tc_flow *flow)
{}

static void remove_unready_flow(struct mlx5e_tc_flow *flow)
{}

bool mlx5e_tc_is_vf_tunnel(struct net_device *out_dev, struct net_device *route_dev)
{}

int mlx5e_tc_query_route_vport(struct net_device *out_dev, struct net_device *route_dev, u16 *vport)
{}

static int
verify_attr_actions(u32 actions, struct netlink_ext_ack *extack)
{}

static bool
has_encap_dests(struct mlx5_flow_attr *attr)
{}

static int
post_process_attr(struct mlx5e_tc_flow *flow,
		  struct mlx5_flow_attr *attr,
		  struct netlink_ext_ack *extack)
{}

static int
mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
		      struct mlx5e_tc_flow *flow,
		      struct netlink_ext_ack *extack)
{}

static bool mlx5_flow_has_geneve_opt(struct mlx5e_tc_flow *flow)
{}

static void free_branch_attr(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr)
{}

static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
				  struct mlx5e_tc_flow *flow)
{}

struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow)
{}

/* Iterate over tmp_list of flows attached to flow_list head. */
void mlx5e_put_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list)
{}

static void mlx5e_tc_del_fdb_peer_flow(struct mlx5e_tc_flow *flow,
				       int peer_index)
{}

static void mlx5e_tc_del_fdb_peers_flow(struct mlx5e_tc_flow *flow)
{}

static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
			      struct mlx5e_tc_flow *flow)
{}

static bool flow_requires_tunnel_mapping(u32 chain, struct flow_cls_offload *f)
{}

static int
enc_opts_is_dont_care_or_full_match(struct mlx5e_priv *priv,
				    struct flow_dissector_key_enc_opts *opts,
				    struct netlink_ext_ack *extack,
				    bool *dont_care)
{}

#define COPY_DISSECTOR(rule, diss_key, dst)

static int mlx5e_get_flow_tunnel_id(struct mlx5e_priv *priv,
				    struct mlx5e_tc_flow *flow,
				    struct flow_cls_offload *f,
				    struct net_device *filter_dev)
{}

static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow)
{}

void mlx5e_tc_set_ethertype(struct mlx5_core_dev *mdev,
			    struct flow_match_basic *match, bool outer,
			    void *headers_c, void *headers_v)
{}

u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer)
{}

/* Tunnel device follows RFC 6040, see include/net/inet_ecn.h.
 * And changes inner ip_ecn depending on inner and outer ip_ecn as follows:
 *      +---------+----------------------------------------+
 *      |Arriving |         Arriving Outer Header          |
 *      |   Inner +---------+---------+---------+----------+
 *      |  Header | Not-ECT | ECT(0)  | ECT(1)  |   CE     |
 *      +---------+---------+---------+---------+----------+
 *      | Not-ECT | Not-ECT | Not-ECT | Not-ECT | <drop>   |
 *      |  ECT(0) |  ECT(0) | ECT(0)  | ECT(1)  |   CE*    |
 *      |  ECT(1) |  ECT(1) | ECT(1)  | ECT(1)* |   CE*    |
 *      |    CE   |   CE    |  CE     | CE      |   CE     |
 *      +---------+---------+---------+---------+----------+
 *
 * Tc matches on inner after decapsulation on tunnel device, but hw offload matches
 * the inner ip_ecn value before hardware decap action.
 *
 * Cells marked are changed from original inner packet ip_ecn value during decap, and
 * so matching those values on inner ip_ecn before decap will fail.
 *
 * The following helper allows offload when inner ip_ecn won't be changed by outer ip_ecn,
 * except for the outer ip_ecn = CE, where in all cases inner ip_ecn will be changed to CE,
 * and such we can drop the inner ip_ecn=CE match.
 */

static int mlx5e_tc_verify_tunnel_ecn(struct mlx5e_priv *priv,
				      struct flow_cls_offload *f,
				      bool *match_inner_ecn)
{}

static int parse_tunnel_attr(struct mlx5e_priv *priv,
			     struct mlx5e_tc_flow *flow,
			     struct mlx5_flow_spec *spec,
			     struct flow_cls_offload *f,
			     struct net_device *filter_dev,
			     u8 *match_level,
			     bool *match_inner)
{}

static void *get_match_inner_headers_criteria(struct mlx5_flow_spec *spec)
{}

static void *get_match_inner_headers_value(struct mlx5_flow_spec *spec)
{}

static void *get_match_outer_headers_criteria(struct mlx5_flow_spec *spec)
{}

static void *get_match_outer_headers_value(struct mlx5_flow_spec *spec)
{}

void *mlx5e_get_match_headers_value(u32 flags, struct mlx5_flow_spec *spec)
{}

void *mlx5e_get_match_headers_criteria(u32 flags, struct mlx5_flow_spec *spec)
{}

static int mlx5e_flower_parse_meta(struct net_device *filter_dev,
				   struct flow_cls_offload *f)
{}

static bool skip_key_basic(struct net_device *filter_dev,
			   struct flow_cls_offload *f)
{}

static int __parse_cls_flower(struct mlx5e_priv *priv,
			      struct mlx5e_tc_flow *flow,
			      struct mlx5_flow_spec *spec,
			      struct flow_cls_offload *f,
			      struct net_device *filter_dev,
			      u8 *inner_match_level, u8 *outer_match_level)
{}

static int parse_cls_flower(struct mlx5e_priv *priv,
			    struct mlx5e_tc_flow *flow,
			    struct mlx5_flow_spec *spec,
			    struct flow_cls_offload *f,
			    struct net_device *filter_dev)
{}

struct mlx5_fields {};

#define OFFLOAD(fw_field, field_bsize, field_mask, field, off, match_field)

/* masked values are the same and there are no rewrites that do not have a
 * match.
 */
#define SAME_VAL_MASK(type, valp, maskp, matchvalp, matchmaskp)

static bool cmp_val_mask(void *valp, void *maskp, void *matchvalp,
			 void *matchmaskp, u8 bsize)
{}

static struct mlx5_fields fields[] =;

static u32 mask_field_get(void *mask, struct mlx5_fields *f)
{}

static void mask_field_clear(void *mask, struct mlx5_fields *f)
{}

static int offload_pedit_fields(struct mlx5e_priv *priv,
				int namespace,
				struct mlx5e_tc_flow_parse_attr *parse_attr,
				u32 *action_flags,
				struct netlink_ext_ack *extack)
{}

static const struct pedit_headers zero_masks =;

static int verify_offload_pedit_fields(struct mlx5e_priv *priv,
				       struct mlx5e_tc_flow_parse_attr *parse_attr,
				       struct netlink_ext_ack *extack)
{}

static int alloc_tc_pedit_action(struct mlx5e_priv *priv, int namespace,
				 struct mlx5e_tc_flow_parse_attr *parse_attr,
				 u32 *action_flags,
				 struct netlink_ext_ack *extack)
{}

struct ip_ttl_word {};

struct ipv6_hoplimit_word {};

static bool
is_flow_action_modify_ip_header(struct flow_action *flow_action)
{}

static bool modify_header_match_supported(struct mlx5e_priv *priv,
					  struct mlx5_flow_spec *spec,
					  struct flow_action *flow_action,
					  u32 actions,
					  struct netlink_ext_ack *extack)
{}

static bool
actions_match_supported_fdb(struct mlx5e_priv *priv,
			    struct mlx5e_tc_flow *flow,
			    struct netlink_ext_ack *extack)
{}

static bool
actions_match_supported(struct mlx5e_priv *priv,
			struct flow_action *flow_action,
			u32 actions,
			struct mlx5e_tc_flow_parse_attr *parse_attr,
			struct mlx5e_tc_flow *flow,
			struct netlink_ext_ack *extack)
{}

static bool same_port_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
{}

bool mlx5e_same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
{}

static int
actions_prepare_mod_hdr_actions(struct mlx5e_priv *priv,
				struct mlx5e_tc_flow *flow,
				struct mlx5_flow_attr *attr,
				struct netlink_ext_ack *extack)
{}

static struct mlx5_flow_attr*
mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr,
				   enum mlx5_flow_namespace_type ns_type)
{}

struct mlx5_flow_attr *
mlx5e_tc_get_encap_attr(struct mlx5e_tc_flow *flow)
{}

void
mlx5e_tc_unoffload_flow_post_acts(struct mlx5e_tc_flow *flow)
{}

static void
free_flow_post_acts(struct mlx5e_tc_flow *flow)
{}

int
mlx5e_tc_offload_flow_post_acts(struct mlx5e_tc_flow *flow)
{}

/* TC filter rule HW translation:
 *
 * +---------------------+
 * + ft prio (tc chain)  +
 * + original match      +
 * +---------------------+
 *           |
 *           | if multi table action
 *           |
 *           v
 * +---------------------+
 * + post act ft         |<----.
 * + match fte id        |     | split on multi table action
 * + do actions          |-----'
 * +---------------------+
 *           |
 *           |
 *           v
 * Do rest of the actions after last multi table action.
 */
static int
alloc_flow_post_acts(struct mlx5e_tc_flow *flow, struct netlink_ext_ack *extack)
{}

static int
set_branch_dest_ft(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr)
{}

static int
alloc_branch_attr(struct mlx5e_tc_flow *flow,
		  struct mlx5e_tc_act_branch_ctrl *cond,
		  struct mlx5_flow_attr **cond_attr,
		  u32 *jump_count,
		  struct netlink_ext_ack *extack)
{}

static void
dec_jump_count(struct flow_action_entry *act, struct mlx5e_tc_act *tc_act,
	       struct mlx5_flow_attr *attr, struct mlx5e_priv *priv,
	       struct mlx5e_tc_jump_state *jump_state)
{}

static int
parse_branch_ctrl(struct flow_action_entry *act, struct mlx5e_tc_act *tc_act,
		  struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr,
		  struct mlx5e_tc_jump_state *jump_state,
		  struct netlink_ext_ack *extack)
{}

static int
parse_tc_actions(struct mlx5e_tc_act_parse_state *parse_state,
		 struct flow_action *flow_action)
{}

static int
flow_action_supported(struct flow_action *flow_action,
		      struct netlink_ext_ack *extack)
{}

static int
parse_tc_nic_actions(struct mlx5e_priv *priv,
		     struct flow_action *flow_action,
		     struct mlx5e_tc_flow *flow,
		     struct netlink_ext_ack *extack)
{}

static bool is_merged_eswitch_vfs(struct mlx5e_priv *priv,
				  struct net_device *peer_netdev)
{}

static bool same_hw_reps(struct mlx5e_priv *priv,
			 struct net_device *peer_netdev)
{}

static bool is_lag_dev(struct mlx5e_priv *priv,
		       struct net_device *peer_netdev)
{}

static bool is_multiport_eligible(struct mlx5e_priv *priv, struct net_device *out_dev)
{}

bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
				    struct net_device *out_dev)
{}

int mlx5e_set_fwd_to_int_port_actions(struct mlx5e_priv *priv,
				      struct mlx5_flow_attr *attr,
				      int ifindex,
				      enum mlx5e_tc_int_port_type type,
				      u32 *action,
				      int out_index)
{}

static int
parse_tc_fdb_actions(struct mlx5e_priv *priv,
		     struct flow_action *flow_action,
		     struct mlx5e_tc_flow *flow,
		     struct netlink_ext_ack *extack)
{}

static void get_flags(int flags, unsigned long *flow_flags)
{}

static const struct rhashtable_params tc_ht_params =;

static struct rhashtable *get_tc_ht(struct mlx5e_priv *priv,
				    unsigned long flags)
{}

static bool is_peer_flow_needed(struct mlx5e_tc_flow *flow)
{}

struct mlx5_flow_attr *
mlx5_alloc_flow_attr(enum mlx5_flow_namespace_type type)
{}

static void
mlx5_free_flow_attr_actions(struct mlx5e_tc_flow *flow, struct mlx5_flow_attr *attr)
{}

static int
mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size,
		 struct flow_cls_offload *f, unsigned long flow_flags,
		 struct mlx5e_tc_flow_parse_attr **__parse_attr,
		 struct mlx5e_tc_flow **__flow)
{}

static void
mlx5e_flow_attr_init(struct mlx5_flow_attr *attr,
		     struct mlx5e_tc_flow_parse_attr *parse_attr,
		     struct flow_cls_offload *f)
{}

static void
mlx5e_flow_esw_attr_init(struct mlx5_flow_attr *attr,
			 struct mlx5e_priv *priv,
			 struct mlx5e_tc_flow_parse_attr *parse_attr,
			 struct flow_cls_offload *f,
			 struct mlx5_eswitch_rep *in_rep,
			 struct mlx5_core_dev *in_mdev)
{}

static struct mlx5e_tc_flow *
__mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
		     struct flow_cls_offload *f,
		     unsigned long flow_flags,
		     struct net_device *filter_dev,
		     struct mlx5_eswitch_rep *in_rep,
		     struct mlx5_core_dev *in_mdev)
{}

static int mlx5e_tc_add_fdb_peer_flow(struct flow_cls_offload *f,
				      struct mlx5e_tc_flow *flow,
				      unsigned long flow_flags,
				      struct mlx5_eswitch *peer_esw)
{}

static int
mlx5e_add_fdb_flow(struct mlx5e_priv *priv,
		   struct flow_cls_offload *f,
		   unsigned long flow_flags,
		   struct net_device *filter_dev,
		   struct mlx5e_tc_flow **__flow)
{}

static int
mlx5e_add_nic_flow(struct mlx5e_priv *priv,
		   struct flow_cls_offload *f,
		   unsigned long flow_flags,
		   struct net_device *filter_dev,
		   struct mlx5e_tc_flow **__flow)
{}

static int
mlx5e_tc_add_flow(struct mlx5e_priv *priv,
		  struct flow_cls_offload *f,
		  unsigned long flags,
		  struct net_device *filter_dev,
		  struct mlx5e_tc_flow **flow)
{}

static bool is_flow_rule_duplicate_allowed(struct net_device *dev,
					   struct mlx5e_rep_priv *rpriv)
{}

/* As IPsec and TC order is not aligned between software and hardware-offload,
 * either IPsec offload or TC offload, not both, is allowed for a specific interface.
 */
static bool is_tc_ipsec_order_check_needed(struct net_device *filter, struct mlx5e_priv *priv)
{}

static int mlx5e_tc_block_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
{}

static void mlx5e_tc_unblock_ipsec_offload(struct net_device *filter, struct mlx5e_priv *priv)
{}

int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv,
			   struct flow_cls_offload *f, unsigned long flags)
{}

static bool same_flow_direction(struct mlx5e_tc_flow *flow, int flags)
{}

int mlx5e_delete_flower(struct net_device *dev, struct mlx5e_priv *priv,
			struct flow_cls_offload *f, unsigned long flags)
{}

int mlx5e_tc_fill_action_stats(struct mlx5e_priv *priv,
			       struct flow_offload_action *fl_act)
{}

int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
		       struct flow_cls_offload *f, unsigned long flags)
{}

static int apply_police_params(struct mlx5e_priv *priv, u64 rate,
			       struct netlink_ext_ack *extack)
{}

static int
tc_matchall_police_validate(const struct flow_action *action,
			    const struct flow_action_entry *act,
			    struct netlink_ext_ack *extack)
{}

static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,
					struct flow_action *flow_action,
					struct netlink_ext_ack *extack)
{}

int mlx5e_tc_configure_matchall(struct mlx5e_priv *priv,
				struct tc_cls_matchall_offload *ma)
{}

int mlx5e_tc_delete_matchall(struct mlx5e_priv *priv,
			     struct tc_cls_matchall_offload *ma)
{}

static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
					      struct mlx5e_priv *peer_priv)
{}

static int mlx5e_tc_netdev_event(struct notifier_block *this,
				 unsigned long event, void *ptr)
{}

static int mlx5e_tc_nic_create_miss_table(struct mlx5e_priv *priv)
{}

static void mlx5e_tc_nic_destroy_miss_table(struct mlx5e_priv *priv)
{}

int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
{}

static void _mlx5e_tc_del_flow(void *ptr, void *arg)
{}

void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv)
{}

int mlx5e_tc_ht_init(struct rhashtable *tc_ht)
{}

void mlx5e_tc_ht_cleanup(struct rhashtable *tc_ht)
{}

int mlx5e_tc_esw_init(struct mlx5_rep_uplink_priv *uplink_priv)
{}

void mlx5e_tc_esw_cleanup(struct mlx5_rep_uplink_priv *uplink_priv)
{}

int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags)
{}

void mlx5e_tc_clean_fdb_peer_flows(struct mlx5_eswitch *esw)
{}

void mlx5e_tc_reoffload_flows_work(struct work_struct *work)
{}

static int mlx5e_setup_tc_cls_flower(struct mlx5e_priv *priv,
				     struct flow_cls_offload *cls_flower,
				     unsigned long flags)
{}

int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
			    void *cb_priv)
{}

static bool mlx5e_tc_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
				    struct mlx5e_tc_update_priv *tc_priv,
				    u32 tunnel_id)
{}

static bool mlx5e_tc_restore_skb_tc_meta(struct sk_buff *skb, struct mlx5_tc_ct_priv *ct_priv,
					 struct mlx5_mapped_obj *mapped_obj, u32 zone_restore_id,
					 u32 tunnel_id,  struct mlx5e_tc_update_priv *tc_priv)
{}

static void mlx5e_tc_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *skb,
					struct mlx5_mapped_obj *mapped_obj,
					struct mlx5e_tc_update_priv *tc_priv)
{}

static bool mlx5e_tc_restore_skb_int_port(struct mlx5e_priv *priv, struct sk_buff *skb,
					  struct mlx5_mapped_obj *mapped_obj,
					  struct mlx5e_tc_update_priv *tc_priv,
					  u32 tunnel_id)
{}

bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb,
			 struct mapping_ctx *mapping_ctx, u32 mapped_obj_id,
			 struct mlx5_tc_ct_priv *ct_priv,
			 u32 zone_restore_id, u32 tunnel_id,
			 struct mlx5e_tc_update_priv *tc_priv)
{}

bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb)
{}

static struct mapping_ctx *
mlx5e_get_priv_obj_mapping(struct mlx5e_priv *priv)
{}

int mlx5e_tc_action_miss_mapping_get(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr,
				     u64 act_miss_cookie, u32 *act_miss_mapping)
{}

void mlx5e_tc_action_miss_mapping_put(struct mlx5e_priv *priv, struct mlx5_flow_attr *attr,
				      u32 act_miss_mapping)
{}