linux/drivers/net/ethernet/sfc/tc.c

// SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************
 * Driver for Solarflare network controllers and boards
 * Copyright 2019 Solarflare Communications Inc.
 * Copyright 2020-2022 Xilinx Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation, incorporated herein by reference.
 */

#include <net/pkt_cls.h>
#include <net/vxlan.h>
#include <net/geneve.h>
#include <net/tc_act/tc_ct.h>
#include "tc.h"
#include "tc_bindings.h"
#include "tc_encap_actions.h"
#include "tc_conntrack.h"
#include "mae.h"
#include "ef100_rep.h"
#include "efx.h"

enum efx_encap_type efx_tc_indr_netdev_type(struct net_device *net_dev)
{}

#define EFX_TC_HDR_TYPE_TTL_MASK
/* Hoplimit is stored in the most significant byte in the pedit ipv6 header action */
#define EFX_TC_HDR_TYPE_HLIMIT_MASK
#define EFX_EFV_PF
/* Look up the representor information (efv) for a device.
 * May return NULL for the PF (us), or an error pointer for a device that
 * isn't supported as a TC offload endpoint
 */
struct efx_rep *efx_tc_flower_lookup_efv(struct efx_nic *efx,
					 struct net_device *dev)
{}

/* Convert a driver-internal vport ID into an internal device (PF or VF) */
static s64 efx_tc_flower_internal_mport(struct efx_nic *efx, struct efx_rep *efv)
{}

/* Convert a driver-internal vport ID into an external device (wire or VF) */
s64 efx_tc_flower_external_mport(struct efx_nic *efx, struct efx_rep *efv)
{}

static const struct rhashtable_params efx_tc_mac_ht_params =;

static const struct rhashtable_params efx_tc_encap_match_ht_params =;

static const struct rhashtable_params efx_tc_match_action_ht_params =;

static const struct rhashtable_params efx_tc_lhs_rule_ht_params =;

static const struct rhashtable_params efx_tc_recirc_ht_params =;

static struct efx_tc_mac_pedit_action *efx_tc_flower_get_mac(struct efx_nic *efx,
							     unsigned char h_addr[ETH_ALEN],
							     struct netlink_ext_ack *extack)
{}

static void efx_tc_flower_put_mac(struct efx_nic *efx,
				  struct efx_tc_mac_pedit_action *ped)
{}

static void efx_tc_free_action_set(struct efx_nic *efx,
				   struct efx_tc_action_set *act, bool in_hw)
{}

static void efx_tc_free_action_set_list(struct efx_nic *efx,
					struct efx_tc_action_set_list *acts,
					bool in_hw)
{}

/* Boilerplate for the simple 'copy a field' cases */
#define _MAP_KEY_AND_MASK(_name, _type, _tcget, _tcfield, _field)
#define MAP_KEY_AND_MASK(_name, _type, _tcfield, _field)
#define MAP_ENC_KEY_AND_MASK(_name, _type, _tcget, _tcfield, _field)

static int efx_tc_flower_parse_match(struct efx_nic *efx,
				     struct flow_rule *rule,
				     struct efx_tc_match *match,
				     struct netlink_ext_ack *extack)
{}

static void efx_tc_flower_release_encap_match(struct efx_nic *efx,
					      struct efx_tc_encap_match *encap)
{}

static int efx_tc_flower_record_encap_match(struct efx_nic *efx,
					    struct efx_tc_match *match,
					    enum efx_encap_type type,
					    enum efx_tc_em_pseudo_type em_type,
					    u8 child_ip_tos_mask,
					    __be16 child_udp_sport_mask,
					    struct netlink_ext_ack *extack)
{}

static struct efx_tc_recirc_id *efx_tc_get_recirc_id(struct efx_nic *efx,
						     u32 chain_index,
						     struct net_device *net_dev)
{}

static void efx_tc_put_recirc_id(struct efx_nic *efx, struct efx_tc_recirc_id *rid)
{}

static void efx_tc_delete_rule(struct efx_nic *efx, struct efx_tc_flow_rule *rule)
{}

static const char *efx_tc_encap_type_name(enum efx_encap_type typ)
{}

/* For details of action order constraints refer to SF-123102-TC-1§12.6.1 */
enum efx_tc_action_order {};
/* Determine whether we can add @new action without violating order */
static bool efx_tc_flower_action_order_ok(const struct efx_tc_action_set *act,
					  enum efx_tc_action_order new)
{}

/**
 * DOC: TC conntrack sequences
 *
 * The MAE hardware can handle at most two rounds of action rule matching,
 * consequently we support conntrack through the notion of a "left-hand side
 * rule".  This is a rule which typically contains only the actions "ct" and
 * "goto chain N", and corresponds to one or more "right-hand side rules" in
 * chain N, which typically match on +trk+est, and may perform ct(nat) actions.
 * RHS rules go in the Action Rule table as normal but with a nonzero recirc_id
 * (the hardware equivalent of chain_index), while LHS rules may go in either
 * the Action Rule or the Outer Rule table, the latter being preferred for
 * performance reasons, and set both DO_CT and a recirc_id in their response.
 *
 * Besides the RHS rules, there are often also similar rules matching on
 * +trk+new which perform the ct(commit) action.  These are not offloaded.
 */

static bool efx_tc_rule_is_lhs_rule(struct flow_rule *fr,
				    struct efx_tc_match *match)
{}

/* A foreign LHS rule has matches on enc_ keys at the TC layer (including an
 * implied match on enc_ip_proto UDP).  Translate these into non-enc_ keys,
 * so that we can use the same MAE machinery as local LHS rules (and so that
 * the lhs_rules entries have uniform semantics).  It may seem odd to do it
 * this way round, given that the corresponding fields in the MAE MCDIs are
 * all ENC_, but (a) we don't have enc_L2 or enc_ip_proto in struct
 * efx_tc_match_fields and (b) semantically an LHS rule doesn't have inner
 * fields so it's just matching on *the* header rather than the outer header.
 * Make sure that the non-enc_ keys were not already being matched on, as that
 * would imply a rule that needed a triple lookup.  (Hardware can do that,
 * with OR-AR-CT-AR, but it halves packet rate so we avoid it where possible;
 * see efx_tc_flower_flhs_needs_ar().)
 */
static int efx_tc_flower_translate_flhs_match(struct efx_tc_match *match)
{}

/* If a foreign LHS rule wants to match on keys that are only available after
 * encap header identification and parsing, then it can't be done in the Outer
 * Rule lookup, because that lookup determines the encap type used to parse
 * beyond the outer headers.  Thus, such rules must use the OR-AR-CT-AR lookup
 * sequence, with an EM (struct efx_tc_encap_match) in the OR step.
 * Return true iff the passed match requires this.
 */
static bool efx_tc_flower_flhs_needs_ar(struct efx_tc_match *match)
{}

static int efx_tc_flower_handle_lhs_actions(struct efx_nic *efx,
					    struct flow_cls_offload *tc,
					    struct flow_rule *fr,
					    struct net_device *net_dev,
					    struct efx_tc_lhs_rule *rule)

{}

static void efx_tc_flower_release_lhs_actions(struct efx_nic *efx,
					      struct efx_tc_lhs_action *act)
{}

/**
 * struct efx_tc_mangler_state - accumulates 32-bit pedits into fields
 *
 * @dst_mac_32:	dst_mac[0:3] has been populated
 * @dst_mac_16:	dst_mac[4:5] has been populated
 * @src_mac_16:	src_mac[0:1] has been populated
 * @src_mac_32:	src_mac[2:5] has been populated
 * @dst_mac:	h_dest field of ethhdr
 * @src_mac:	h_source field of ethhdr
 *
 * Since FLOW_ACTION_MANGLE comes in 32-bit chunks that do not
 * necessarily equate to whole fields of the packet header, this
 * structure is used to hold the cumulative effect of the partial
 * field pedits that have been processed so far.
 */
struct efx_tc_mangler_state {};

/** efx_tc_complete_mac_mangle() - pull complete field pedits out of @mung
 * @efx:	NIC we're installing a flow rule on
 * @act:	action set (cursor) to update
 * @mung:	accumulated partial mangles
 * @extack:	netlink extended ack for reporting errors
 *
 * Check @mung to find any combinations of partial mangles that can be
 * combined into a complete packet field edit, add that edit to @act,
 * and consume the partial mangles from @mung.
 */

static int efx_tc_complete_mac_mangle(struct efx_nic *efx,
				      struct efx_tc_action_set *act,
				      struct efx_tc_mangler_state *mung,
				      struct netlink_ext_ack *extack)
{}

static int efx_tc_pedit_add(struct efx_nic *efx, struct efx_tc_action_set *act,
			    const struct flow_action_entry *fa,
			    struct netlink_ext_ack *extack)
{}

/**
 * efx_tc_mangle() - handle a single 32-bit (or less) pedit
 * @efx:	NIC we're installing a flow rule on
 * @act:	action set (cursor) to update
 * @fa:		FLOW_ACTION_MANGLE action metadata
 * @mung:	accumulator for partial mangles
 * @extack:	netlink extended ack for reporting errors
 * @match:	original match used along with the mangle action
 *
 * Identify the fields written by a FLOW_ACTION_MANGLE, and record
 * the partial mangle state in @mung.  If this mangle completes an
 * earlier partial mangle, consume and apply to @act by calling
 * efx_tc_complete_mac_mangle().
 */

static int efx_tc_mangle(struct efx_nic *efx, struct efx_tc_action_set *act,
			 const struct flow_action_entry *fa,
			 struct efx_tc_mangler_state *mung,
			 struct netlink_ext_ack *extack,
			 struct efx_tc_match *match)
{}

/**
 * efx_tc_incomplete_mangle() - check for leftover partial pedits
 * @mung:	accumulator for partial mangles
 * @extack:	netlink extended ack for reporting errors
 *
 * Since the MAE can only overwrite whole fields, any partial
 * field mangle left over on reaching packet delivery (mirred or
 * end of TC actions) cannot be offloaded.  Check for any such
 * and reject them with -%EOPNOTSUPP.
 */

static int efx_tc_incomplete_mangle(struct efx_tc_mangler_state *mung,
				    struct netlink_ext_ack *extack)
{}

static int efx_tc_flower_replace_foreign_lhs_ar(struct efx_nic *efx,
						struct flow_cls_offload *tc,
						struct flow_rule *fr,
						struct efx_tc_match *match,
						struct net_device *net_dev)
{}

static int efx_tc_flower_replace_foreign_lhs(struct efx_nic *efx,
					     struct flow_cls_offload *tc,
					     struct flow_rule *fr,
					     struct efx_tc_match *match,
					     struct net_device *net_dev)
{}

static int efx_tc_flower_replace_foreign(struct efx_nic *efx,
					 struct net_device *net_dev,
					 struct flow_cls_offload *tc)
{}

static int efx_tc_flower_replace_lhs(struct efx_nic *efx,
				     struct flow_cls_offload *tc,
				     struct flow_rule *fr,
				     struct efx_tc_match *match,
				     struct efx_rep *efv,
				     struct net_device *net_dev)
{}

static int efx_tc_flower_replace(struct efx_nic *efx,
				 struct net_device *net_dev,
				 struct flow_cls_offload *tc,
				 struct efx_rep *efv)
{}

static int efx_tc_flower_destroy(struct efx_nic *efx,
				 struct net_device *net_dev,
				 struct flow_cls_offload *tc)
{}

static int efx_tc_flower_stats(struct efx_nic *efx, struct net_device *net_dev,
			       struct flow_cls_offload *tc)
{}

int efx_tc_flower(struct efx_nic *efx, struct net_device *net_dev,
		  struct flow_cls_offload *tc, struct efx_rep *efv)
{}

static int efx_tc_configure_default_rule(struct efx_nic *efx, u32 ing_port,
					 u32 eg_port, struct efx_tc_flow_rule *rule)
{}

static int efx_tc_configure_default_rule_pf(struct efx_nic *efx)
{}

static int efx_tc_configure_default_rule_wire(struct efx_nic *efx)
{}

int efx_tc_configure_default_rule_rep(struct efx_rep *efv)
{}

void efx_tc_deconfigure_default_rule(struct efx_nic *efx,
				     struct efx_tc_flow_rule *rule)
{}

static int efx_tc_configure_fallback_acts(struct efx_nic *efx, u32 eg_port,
					  struct efx_tc_action_set_list *acts)
{}

static int efx_tc_configure_fallback_acts_pf(struct efx_nic *efx)
{}

static int efx_tc_configure_fallback_acts_reps(struct efx_nic *efx)
{}

static void efx_tc_deconfigure_fallback_acts(struct efx_nic *efx,
					     struct efx_tc_action_set_list *acts)
{}

static int efx_tc_configure_rep_mport(struct efx_nic *efx)
{}

static void efx_tc_deconfigure_rep_mport(struct efx_nic *efx)
{}

int efx_tc_insert_rep_filters(struct efx_nic *efx)
{}

void efx_tc_remove_rep_filters(struct efx_nic *efx)
{}

int efx_init_tc(struct efx_nic *efx)
{}

void efx_fini_tc(struct efx_nic *efx)
{}

/* At teardown time, all TC filter rules (and thus all resources they created)
 * should already have been removed.  If we find any in our hashtables, make a
 * cursory attempt to clean up the software side.
 */
static void efx_tc_encap_match_free(void *ptr, void *__unused)
{}

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

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

static void efx_tc_mac_free(void *ptr, void *__unused)
{}

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

int efx_init_struct_tc(struct efx_nic *efx)
{}

void efx_fini_struct_tc(struct efx_nic *efx)
{}