net/mlx5: Refactor tc miss handling to a single function
Move tc miss handling code to en_tc.c, and remove duplicate code. Signed-off-by: Paul Blakey <paulb@nvidia.com> Reviewed-by: Roi Dayan <roid@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
03a283cdc8
commit
93a1ab2c54
|
@ -1,7 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
/* Copyright (c) 2020 Mellanox Technologies. */
|
||||
|
||||
#include <net/dst_metadata.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_macvlan.h>
|
||||
#include <linux/list.h>
|
||||
|
@ -665,230 +664,54 @@ void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
|
|||
mlx5e_rep_indr_block_unbind);
|
||||
}
|
||||
|
||||
static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
|
||||
struct mlx5e_tc_update_priv *tc_priv,
|
||||
u32 tunnel_id)
|
||||
{
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct tunnel_match_enc_opts enc_opts = {};
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
struct metadata_dst *tun_dst;
|
||||
struct tunnel_match_key key;
|
||||
u32 tun_id, enc_opts_id;
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
enc_opts_id = tunnel_id & ENC_OPTS_BITS_MASK;
|
||||
tun_id = tunnel_id >> ENC_OPTS_BITS;
|
||||
|
||||
if (!tun_id)
|
||||
return true;
|
||||
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
|
||||
err = mapping_find(uplink_priv->tunnel_mapping, tun_id, &key);
|
||||
if (err) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find tunnel for tun_id: %d, err: %d\n",
|
||||
tun_id, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enc_opts_id) {
|
||||
err = mapping_find(uplink_priv->tunnel_enc_opts_mapping,
|
||||
enc_opts_id, &enc_opts);
|
||||
if (err) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find tunnel (opts) for tun_id: %d, err: %d\n",
|
||||
enc_opts_id, err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (key.enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
|
||||
tun_dst = __ip_tun_set_dst(key.enc_ipv4.src, key.enc_ipv4.dst,
|
||||
key.enc_ip.tos, key.enc_ip.ttl,
|
||||
key.enc_tp.dst, TUNNEL_KEY,
|
||||
key32_to_tunnel_id(key.enc_key_id.keyid),
|
||||
enc_opts.key.len);
|
||||
} else if (key.enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
|
||||
tun_dst = __ipv6_tun_set_dst(&key.enc_ipv6.src, &key.enc_ipv6.dst,
|
||||
key.enc_ip.tos, key.enc_ip.ttl,
|
||||
key.enc_tp.dst, 0, TUNNEL_KEY,
|
||||
key32_to_tunnel_id(key.enc_key_id.keyid),
|
||||
enc_opts.key.len);
|
||||
} else {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't restore tunnel, unsupported addr_type: %d\n",
|
||||
key.enc_control.addr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tun_dst) {
|
||||
netdev_dbg(priv->netdev, "Couldn't restore tunnel, no tun_dst\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
tun_dst->u.tun_info.key.tp_src = key.enc_tp.src;
|
||||
|
||||
if (enc_opts.key.len)
|
||||
ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
|
||||
enc_opts.key.data,
|
||||
enc_opts.key.len,
|
||||
enc_opts.key.dst_opt_type);
|
||||
|
||||
skb_dst_set(skb, (struct dst_entry *)tun_dst);
|
||||
dev = dev_get_by_index(&init_net, key.filter_ifindex);
|
||||
if (!dev) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find tunnel device with ifindex: %d\n",
|
||||
key.filter_ifindex);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set fwd_dev so we do dev_put() after datapath */
|
||||
tc_priv->fwd_dev = dev;
|
||||
|
||||
skb->dev = dev;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mlx5e_restore_skb_chain(struct sk_buff *skb, u32 chain, u32 reg_c1,
|
||||
struct mlx5e_tc_update_priv *tc_priv)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(skb->dev);
|
||||
u32 tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK;
|
||||
|
||||
if (chain) {
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
struct tc_skb_ext *tc_skb_ext;
|
||||
struct mlx5_eswitch *esw;
|
||||
u32 zone_restore_id;
|
||||
|
||||
tc_skb_ext = tc_skb_ext_alloc(skb);
|
||||
if (!tc_skb_ext) {
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
tc_skb_ext->chain = chain;
|
||||
zone_restore_id = reg_c1 & ESW_ZONE_ID_MASK;
|
||||
esw = priv->mdev->priv.eswitch;
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
if (!mlx5e_tc_ct_restore_flow(uplink_priv->ct_priv, skb,
|
||||
zone_restore_id))
|
||||
return false;
|
||||
}
|
||||
|
||||
return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id);
|
||||
}
|
||||
|
||||
static void mlx5_rep_tc_post_napi_receive(struct mlx5e_tc_update_priv *tc_priv)
|
||||
{
|
||||
if (tc_priv->fwd_dev)
|
||||
dev_put(tc_priv->fwd_dev);
|
||||
}
|
||||
|
||||
static void mlx5e_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *skb,
|
||||
struct mlx5_mapped_obj *mapped_obj,
|
||||
struct mlx5e_tc_update_priv *tc_priv)
|
||||
{
|
||||
if (!mlx5e_restore_tunnel(priv, skb, tc_priv, mapped_obj->sample.tunnel_id)) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Failed to restore tunnel info for sampled packet\n");
|
||||
return;
|
||||
}
|
||||
mlx5e_tc_sample_skb(skb, mapped_obj);
|
||||
mlx5_rep_tc_post_napi_receive(tc_priv);
|
||||
}
|
||||
|
||||
static bool mlx5e_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,
|
||||
bool *forward_tx,
|
||||
u32 reg_c1)
|
||||
{
|
||||
u32 tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK;
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
|
||||
/* Tunnel restore takes precedence over int port restore */
|
||||
if (tunnel_id)
|
||||
return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id);
|
||||
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
|
||||
if (mlx5e_tc_int_port_dev_fwd(uplink_priv->int_port_priv, skb,
|
||||
mapped_obj->int_port_metadata, forward_tx)) {
|
||||
/* Set fwd_dev for future dev_put */
|
||||
tc_priv->fwd_dev = skb->dev;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void mlx5e_rep_tc_receive(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
u32 reg_c1 = be32_to_cpu(cqe->ft_metadata);
|
||||
u32 reg_c0, reg_c1, zone_restore_id, tunnel_id;
|
||||
struct mlx5e_tc_update_priv tc_priv = {};
|
||||
struct mlx5_mapped_obj mapped_obj;
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
struct mlx5_tc_ct_priv *ct_priv;
|
||||
struct mapping_ctx *mapping_ctx;
|
||||
struct mlx5_eswitch *esw;
|
||||
bool forward_tx = false;
|
||||
struct mlx5e_priv *priv;
|
||||
u32 reg_c0;
|
||||
int err;
|
||||
|
||||
reg_c0 = (be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK);
|
||||
if (!reg_c0 || reg_c0 == MLX5_FS_DEFAULT_FLOW_TAG)
|
||||
goto forward;
|
||||
|
||||
/* If reg_c0 is not equal to the default flow tag then skb->mark
|
||||
/* If mapped_obj_id is not equal to the default flow tag then skb->mark
|
||||
* is not supported and must be reset back to 0.
|
||||
*/
|
||||
skb->mark = 0;
|
||||
|
||||
priv = netdev_priv(skb->dev);
|
||||
esw = priv->mdev->priv.eswitch;
|
||||
err = mapping_find(esw->offloads.reg_c0_obj_pool, reg_c0, &mapped_obj);
|
||||
if (err) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find mapped object for reg_c0: %d, err: %d\n",
|
||||
reg_c0, err);
|
||||
goto free_skb;
|
||||
}
|
||||
mapping_ctx = esw->offloads.reg_c0_obj_pool;
|
||||
reg_c1 = be32_to_cpu(cqe->ft_metadata);
|
||||
zone_restore_id = reg_c1 & ESW_ZONE_ID_MASK;
|
||||
tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK;
|
||||
|
||||
if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) {
|
||||
if (!mlx5e_restore_skb_chain(skb, mapped_obj.chain, reg_c1, &tc_priv) &&
|
||||
!mlx5_ipsec_is_rx_flow(cqe))
|
||||
goto free_skb;
|
||||
} else if (mapped_obj.type == MLX5_MAPPED_OBJ_SAMPLE) {
|
||||
mlx5e_restore_skb_sample(priv, skb, &mapped_obj, &tc_priv);
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
ct_priv = uplink_priv->ct_priv;
|
||||
|
||||
if (!mlx5_ipsec_is_rx_flow(cqe) &&
|
||||
!mlx5e_tc_update_skb(cqe, skb, mapping_ctx, reg_c0, ct_priv, zone_restore_id, tunnel_id,
|
||||
&tc_priv))
|
||||
goto free_skb;
|
||||
} else if (mapped_obj.type == MLX5_MAPPED_OBJ_INT_PORT_METADATA) {
|
||||
if (!mlx5e_restore_skb_int_port(priv, skb, &mapped_obj, &tc_priv,
|
||||
&forward_tx, reg_c1))
|
||||
goto free_skb;
|
||||
} else {
|
||||
netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type);
|
||||
goto free_skb;
|
||||
}
|
||||
|
||||
forward:
|
||||
if (forward_tx)
|
||||
if (tc_priv.skb_done)
|
||||
goto free_skb;
|
||||
|
||||
if (tc_priv.forward_tx)
|
||||
dev_queue_xmit(skb);
|
||||
else
|
||||
napi_gro_receive(rq->cq.napi, skb);
|
||||
|
||||
mlx5_rep_tc_post_napi_receive(&tc_priv);
|
||||
if (tc_priv.fwd_dev)
|
||||
dev_put(tc_priv.fwd_dev);
|
||||
|
||||
return;
|
||||
|
||||
|
|
|
@ -1792,7 +1792,7 @@ static void mlx5e_handle_rx_cqe(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
|||
mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
|
||||
|
||||
if (mlx5e_cqe_regb_chain(cqe))
|
||||
if (!mlx5e_tc_update_skb(cqe, skb)) {
|
||||
if (!mlx5e_tc_update_skb_nic(cqe, skb)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
goto free_wqe;
|
||||
}
|
||||
|
@ -2259,7 +2259,7 @@ static void mlx5e_handle_rx_cqe_mpwrq(struct mlx5e_rq *rq, struct mlx5_cqe64 *cq
|
|||
mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
|
||||
|
||||
if (mlx5e_cqe_regb_chain(cqe))
|
||||
if (!mlx5e_tc_update_skb(cqe, skb)) {
|
||||
if (!mlx5e_tc_update_skb_nic(cqe, skb)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
goto mpwrq_cqe_out;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <net/ipv6_stubs.h>
|
||||
#include <net/bareudp.h>
|
||||
#include <net/bonding.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include "en.h"
|
||||
#include "en/tc/post_act.h"
|
||||
#include "en/tc/act_stats.h"
|
||||
|
@ -5604,46 +5605,219 @@ int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
|
|||
}
|
||||
}
|
||||
|
||||
bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe,
|
||||
struct sk_buff *skb)
|
||||
static bool mlx5e_tc_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
|
||||
struct mlx5e_tc_update_priv *tc_priv,
|
||||
u32 tunnel_id)
|
||||
{
|
||||
u32 chain = 0, chain_tag, reg_b, zone_restore_id;
|
||||
struct mlx5e_priv *priv = netdev_priv(skb->dev);
|
||||
struct mlx5_mapped_obj mapped_obj;
|
||||
struct tc_skb_ext *tc_skb_ext;
|
||||
struct mlx5e_tc_table *tc;
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct tunnel_match_enc_opts enc_opts = {};
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
struct metadata_dst *tun_dst;
|
||||
struct tunnel_match_key key;
|
||||
u32 tun_id, enc_opts_id;
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
reg_b = be32_to_cpu(cqe->ft_metadata);
|
||||
tc = mlx5e_fs_get_tc(priv->fs);
|
||||
chain_tag = reg_b & MLX5E_TC_TABLE_CHAIN_TAG_MASK;
|
||||
enc_opts_id = tunnel_id & ENC_OPTS_BITS_MASK;
|
||||
tun_id = tunnel_id >> ENC_OPTS_BITS;
|
||||
|
||||
err = mapping_find(tc->mapping, chain_tag, &mapped_obj);
|
||||
if (!tun_id)
|
||||
return true;
|
||||
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
|
||||
err = mapping_find(uplink_priv->tunnel_mapping, tun_id, &key);
|
||||
if (err) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find chain for chain tag: %d, err: %d\n",
|
||||
chain_tag, err);
|
||||
"Couldn't find tunnel for tun_id: %d, err: %d\n",
|
||||
tun_id, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) {
|
||||
chain = mapped_obj.chain;
|
||||
tc_skb_ext = tc_skb_ext_alloc(skb);
|
||||
if (WARN_ON(!tc_skb_ext))
|
||||
if (enc_opts_id) {
|
||||
err = mapping_find(uplink_priv->tunnel_enc_opts_mapping,
|
||||
enc_opts_id, &enc_opts);
|
||||
if (err) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find tunnel (opts) for tun_id: %d, err: %d\n",
|
||||
enc_opts_id, err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
switch (key.enc_control.addr_type) {
|
||||
case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
|
||||
tun_dst = __ip_tun_set_dst(key.enc_ipv4.src, key.enc_ipv4.dst,
|
||||
key.enc_ip.tos, key.enc_ip.ttl,
|
||||
key.enc_tp.dst, TUNNEL_KEY,
|
||||
key32_to_tunnel_id(key.enc_key_id.keyid),
|
||||
enc_opts.key.len);
|
||||
break;
|
||||
case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
|
||||
tun_dst = __ipv6_tun_set_dst(&key.enc_ipv6.src, &key.enc_ipv6.dst,
|
||||
key.enc_ip.tos, key.enc_ip.ttl,
|
||||
key.enc_tp.dst, 0, TUNNEL_KEY,
|
||||
key32_to_tunnel_id(key.enc_key_id.keyid),
|
||||
enc_opts.key.len);
|
||||
break;
|
||||
default:
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't restore tunnel, unsupported addr_type: %d\n",
|
||||
key.enc_control.addr_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tun_dst) {
|
||||
netdev_dbg(priv->netdev, "Couldn't restore tunnel, no tun_dst\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
tun_dst->u.tun_info.key.tp_src = key.enc_tp.src;
|
||||
|
||||
if (enc_opts.key.len)
|
||||
ip_tunnel_info_opts_set(&tun_dst->u.tun_info,
|
||||
enc_opts.key.data,
|
||||
enc_opts.key.len,
|
||||
enc_opts.key.dst_opt_type);
|
||||
|
||||
skb_dst_set(skb, (struct dst_entry *)tun_dst);
|
||||
dev = dev_get_by_index(&init_net, key.filter_ifindex);
|
||||
if (!dev) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Couldn't find tunnel device with ifindex: %d\n",
|
||||
key.filter_ifindex);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set fwd_dev so we do dev_put() after datapath */
|
||||
tc_priv->fwd_dev = dev;
|
||||
|
||||
skb->dev = dev;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mlx5e_tc_restore_skb_chain(struct sk_buff *skb, struct mlx5_tc_ct_priv *ct_priv,
|
||||
u32 chain, u32 zone_restore_id,
|
||||
u32 tunnel_id, struct mlx5e_tc_update_priv *tc_priv)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(skb->dev);
|
||||
struct tc_skb_ext *tc_skb_ext;
|
||||
|
||||
if (chain) {
|
||||
if (!mlx5e_tc_ct_restore_flow(ct_priv, skb, zone_restore_id))
|
||||
return false;
|
||||
|
||||
tc_skb_ext = tc_skb_ext_alloc(skb);
|
||||
if (!tc_skb_ext) {
|
||||
WARN_ON(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
tc_skb_ext->chain = chain;
|
||||
}
|
||||
|
||||
zone_restore_id = (reg_b >> MLX5_REG_MAPPING_MOFFSET(NIC_ZONE_RESTORE_TO_REG)) &
|
||||
ESW_ZONE_ID_MASK;
|
||||
if (tc_priv)
|
||||
return mlx5e_tc_restore_tunnel(priv, skb, tc_priv, tunnel_id);
|
||||
|
||||
if (!mlx5e_tc_ct_restore_flow(tc->ct, skb,
|
||||
zone_restore_id))
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!mlx5e_tc_restore_tunnel(priv, skb, tc_priv, mapped_obj->sample.tunnel_id)) {
|
||||
netdev_dbg(priv->netdev,
|
||||
"Failed to restore tunnel info for sampled packet\n");
|
||||
return;
|
||||
}
|
||||
mlx5e_tc_sample_skb(skb, mapped_obj);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct mlx5_rep_uplink_priv *uplink_priv;
|
||||
struct mlx5e_rep_priv *uplink_rpriv;
|
||||
bool forward_tx = false;
|
||||
|
||||
/* Tunnel restore takes precedence over int port restore */
|
||||
if (tunnel_id)
|
||||
return mlx5e_tc_restore_tunnel(priv, skb, tc_priv, tunnel_id);
|
||||
|
||||
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
||||
uplink_priv = &uplink_rpriv->uplink_priv;
|
||||
|
||||
if (mlx5e_tc_int_port_dev_fwd(uplink_priv->int_port_priv, skb,
|
||||
mapped_obj->int_port_metadata, &forward_tx)) {
|
||||
/* Set fwd_dev for future dev_put */
|
||||
tc_priv->fwd_dev = skb->dev;
|
||||
tc_priv->forward_tx = forward_tx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(skb->dev);
|
||||
struct mlx5_mapped_obj mapped_obj;
|
||||
int err;
|
||||
|
||||
err = mapping_find(mapping_ctx, mapped_obj_id, &mapped_obj);
|
||||
if (err) {
|
||||
netdev_dbg(skb->dev,
|
||||
"Couldn't find mapped object for mapped_obj_id: %d, err: %d\n",
|
||||
mapped_obj_id, err);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (mapped_obj.type) {
|
||||
case MLX5_MAPPED_OBJ_CHAIN:
|
||||
return mlx5e_tc_restore_skb_chain(skb, ct_priv, mapped_obj.chain, zone_restore_id,
|
||||
tunnel_id, tc_priv);
|
||||
case MLX5_MAPPED_OBJ_SAMPLE:
|
||||
mlx5e_tc_restore_skb_sample(priv, skb, &mapped_obj, tc_priv);
|
||||
tc_priv->skb_done = true;
|
||||
return true;
|
||||
case MLX5_MAPPED_OBJ_INT_PORT_METADATA:
|
||||
return mlx5e_tc_restore_skb_int_port(priv, skb, &mapped_obj, tc_priv, tunnel_id);
|
||||
default:
|
||||
netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(skb->dev);
|
||||
u32 mapped_obj_id, reg_b, zone_restore_id;
|
||||
struct mlx5_tc_ct_priv *ct_priv;
|
||||
struct mapping_ctx *mapping_ctx;
|
||||
struct mlx5e_tc_table *tc;
|
||||
|
||||
reg_b = be32_to_cpu(cqe->ft_metadata);
|
||||
tc = mlx5e_fs_get_tc(priv->fs);
|
||||
mapped_obj_id = reg_b & MLX5E_TC_TABLE_CHAIN_TAG_MASK;
|
||||
zone_restore_id = (reg_b >> MLX5_REG_MAPPING_MOFFSET(NIC_ZONE_RESTORE_TO_REG)) &
|
||||
ESW_ZONE_ID_MASK;
|
||||
ct_priv = tc->ct;
|
||||
mapping_ctx = tc->mapping;
|
||||
|
||||
return mlx5e_tc_update_skb(cqe, skb, mapping_ctx, mapped_obj_id, ct_priv, zone_restore_id,
|
||||
0, NULL);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,8 @@ int mlx5e_tc_num_filters(struct mlx5e_priv *priv, unsigned long flags);
|
|||
|
||||
struct mlx5e_tc_update_priv {
|
||||
struct net_device *fwd_dev;
|
||||
bool skb_done;
|
||||
bool forward_tx;
|
||||
};
|
||||
|
||||
struct mlx5_nic_flow_attr {
|
||||
|
@ -382,14 +384,19 @@ static inline bool mlx5e_cqe_regb_chain(struct mlx5_cqe64 *cqe)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb);
|
||||
bool mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb);
|
||||
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);
|
||||
#else /* CONFIG_MLX5_CLS_ACT */
|
||||
static inline struct mlx5e_tc_table *mlx5e_tc_table_alloc(void) { return NULL; }
|
||||
static inline void mlx5e_tc_table_free(struct mlx5e_tc_table *tc) {}
|
||||
static inline bool mlx5e_cqe_regb_chain(struct mlx5_cqe64 *cqe)
|
||||
{ return false; }
|
||||
static inline bool
|
||||
mlx5e_tc_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb)
|
||||
mlx5e_tc_update_skb_nic(struct mlx5_cqe64 *cqe, struct sk_buff *skb)
|
||||
{ return true; }
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue