aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@nvidia.com>2021-03-16 17:02:59 +0200
committerDavid S. Miller <davem@davemloft.net>2021-03-16 15:32:22 -0700
commit54d0e963f683362418424f9ce61884a6e1cced38 (patch)
tree901525fc4abd551b10bd0eabf28d55003e7195d1 /drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
parentmlxsw: spectrum: Start using sampling triggers hash table (diff)
downloadwireguard-linux-54d0e963f683362418424f9ce61884a6e1cced38.tar.xz
wireguard-linux-54d0e963f683362418424f9ce61884a6e1cced38.zip
mlxsw: spectrum_matchall: Add support for egress sampling
Allow user space to install a matchall classifier with sample action on egress. This is only supported on Spectrum-2 onwards, so Spectrum-1 will continue to return an error. Programming the hardware to sample on egress is identical to ingress sampling with the sole change of using a different sampling trigger. Upon receiving a sampled packet, the sampling trigger (ingress vs. egress) will be encoded in the mirroring reason in the Completion Queue Element (CQE). The mirroring reason is used to lookup the sampling parameters (e.g., psample group) which are passed to the psample module. Note that locally generated packets that are sampled are simply consumed. This is done for several reasons. First, such packets do not have an ingress netdev given that their Rx local port is the CPU port. This breaks several basic assumptions. Second, sampling using the same interface (tc), but with flower classifier will not result in locally generated packets being sampled given that such packets are not subject to the policy engine. Third, realistically, this is not a big deal given that the vast majority of the packets being transmitted through the port are not locally generated packets. Fourth, if such packets do need to be sampled, they can be sampled with a 'skip_hw' filter and reported to the same sampling group as the data path packets. The software sampling rate can also be adjusted to fit the rate of the locally generated packets which is much lower than the rate of the data path traffic. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
index db3c561ac3ea..3dbf5e53e9ff 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_trap.c
@@ -53,6 +53,8 @@ enum {
MLXSW_SP_MIRROR_REASON_INGRESS = 1,
/* Packet was early dropped. */
MLXSW_SP_MIRROR_REASON_INGRESS_WRED = 9,
+ /* Packet was mirrored from egress. */
+ MLXSW_SP_MIRROR_REASON_EGRESS = 14,
};
static int mlxsw_sp_rx_listener(struct mlxsw_sp *mlxsw_sp, struct sk_buff *skb,
@@ -289,6 +291,56 @@ out:
consume_skb(skb);
}
+static void mlxsw_sp_rx_sample_tx_listener(struct sk_buff *skb, u8 local_port,
+ void *trap_ctx)
+{
+ struct mlxsw_rx_md_info *rx_md_info = &mlxsw_skb_cb(skb)->rx_md_info;
+ struct mlxsw_sp *mlxsw_sp = devlink_trap_ctx_priv(trap_ctx);
+ struct mlxsw_sp_port *mlxsw_sp_port, *mlxsw_sp_port_tx;
+ struct mlxsw_sp_sample_trigger trigger;
+ struct mlxsw_sp_sample_params *params;
+ struct psample_metadata md = {};
+ int err;
+
+ /* Locally generated packets are not reported from the policy engine
+ * trigger, so do not report them from the egress trigger as well.
+ */
+ if (local_port == MLXSW_PORT_CPU_PORT)
+ goto out;
+
+ err = __mlxsw_sp_rx_no_mark_listener(skb, local_port, trap_ctx);
+ if (err)
+ return;
+
+ mlxsw_sp_port = mlxsw_sp->ports[local_port];
+ if (!mlxsw_sp_port)
+ goto out;
+
+ /* Packet was sampled from Tx, so we need to retrieve the sample
+ * parameters based on the Tx port and not the Rx port.
+ */
+ mlxsw_sp_port_tx = mlxsw_sp_sample_tx_port_get(mlxsw_sp, rx_md_info);
+ if (!mlxsw_sp_port_tx)
+ goto out;
+
+ trigger.type = MLXSW_SP_SAMPLE_TRIGGER_TYPE_EGRESS;
+ trigger.local_port = mlxsw_sp_port_tx->local_port;
+ params = mlxsw_sp_sample_trigger_params_lookup(mlxsw_sp, &trigger);
+ if (!params)
+ goto out;
+
+ /* The psample module expects skb->data to point to the start of the
+ * Ethernet header.
+ */
+ skb_push(skb, ETH_HLEN);
+ mlxsw_sp_psample_md_init(mlxsw_sp, &md, skb,
+ mlxsw_sp_port->dev->ifindex, params->truncate,
+ params->trunc_size);
+ psample_sample_packet(params->psample_group, skb, params->rate, &md);
+out:
+ consume_skb(skb);
+}
+
#define MLXSW_SP_TRAP_DROP(_id, _group_id) \
DEVLINK_TRAP_GENERIC(DROP, DROP, _id, \
DEVLINK_TRAP_GROUP_GENERIC_ID_##_group_id, \
@@ -1843,6 +1895,9 @@ mlxsw_sp2_trap_items_arr[] = {
MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_listener, 1,
SP_PKT_SAMPLE,
MLXSW_SP_MIRROR_REASON_INGRESS),
+ MLXSW_RXL_MIRROR(mlxsw_sp_rx_sample_tx_listener, 1,
+ SP_PKT_SAMPLE,
+ MLXSW_SP_MIRROR_REASON_EGRESS),
},
},
};