|
|
d8f823 |
From a4c8a21efaa55f5607829f5b667a06f32e00a2b0 Mon Sep 17 00:00:00 2001
|
|
|
d8f823 |
From: Alaa Hleihel <ahleihel@redhat.com>
|
|
|
d8f823 |
Date: Tue, 19 May 2020 07:48:59 -0400
|
|
|
d8f823 |
Subject: [PATCH 237/312] [netdrv] net/mlx5e: Restore tunnel metadata on miss
|
|
|
d8f823 |
|
|
|
d8f823 |
Message-id: <20200519074934.6303-29-ahleihel@redhat.com>
|
|
|
d8f823 |
Patchwork-id: 310532
|
|
|
d8f823 |
Patchwork-instance: patchwork
|
|
|
d8f823 |
O-Subject: [RHEL8.3 BZ 1663246 28/63] net/mlx5e: Restore tunnel metadata on miss
|
|
|
d8f823 |
Bugzilla: 1790219 1790218 1663246
|
|
|
d8f823 |
RH-Acked-by: Marcelo Leitner <mleitner@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: John Linville <linville@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
|
|
|
d8f823 |
RH-Acked-by: Kamal Heib <kheib@redhat.com>
|
|
|
d8f823 |
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1663246
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1790219
|
|
|
d8f823 |
Bugzilla: http://bugzilla.redhat.com/1790218
|
|
|
d8f823 |
Upstream: v5.7-rc1
|
|
|
d8f823 |
|
|
|
d8f823 |
commit b8ce90370977dbe24d2ed7271b65710ec9c40166
|
|
|
d8f823 |
Author: Paul Blakey <paulb@mellanox.com>
|
|
|
d8f823 |
Date: Sun Feb 16 12:01:36 2020 +0200
|
|
|
d8f823 |
|
|
|
d8f823 |
net/mlx5e: Restore tunnel metadata on miss
|
|
|
d8f823 |
|
|
|
d8f823 |
In tunnel and chains setup, we decapsulate the packets on first chain hop,
|
|
|
d8f823 |
if we miss on later chains, the packet will comes up without tunnel header,
|
|
|
d8f823 |
so it won't be taken by the tunnel device automatically, which fills the
|
|
|
d8f823 |
tunnel metadata, and further tc tunnel matches won't work.
|
|
|
d8f823 |
|
|
|
d8f823 |
On miss, we get the tunnel mapping id, which was set on the chain 0 rule
|
|
|
d8f823 |
that decapsulated the packet. This rule matched the tunnel outer
|
|
|
d8f823 |
headers. From the tunnel mapping id, we get to this tunnel matches
|
|
|
d8f823 |
and restore the equivalent tunnel info metadata dst on the skb.
|
|
|
d8f823 |
We also set the skb->dev to the relevant device (tunnel device).
|
|
|
d8f823 |
Now further tc processing can be done on the relevant device.
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Paul Blakey <paulb@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Roi Dayan <roid@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Oz Shlomo <ozsh@mellanox.com>
|
|
|
d8f823 |
Reviewed-by: Mark Bloch <markb@mellanox.com>
|
|
|
d8f823 |
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
|
|
|
d8f823 |
|
|
|
d8f823 |
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
|
|
|
d8f823 |
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
|
|
|
d8f823 |
---
|
|
|
d8f823 |
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 10 ++-
|
|
|
d8f823 |
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 110 ++++++++++++++++++++++--
|
|
|
d8f823 |
drivers/net/ethernet/mellanox/mlx5/core/en_tc.h | 9 +-
|
|
|
d8f823 |
3 files changed, 117 insertions(+), 12 deletions(-)
|
|
|
d8f823 |
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
|
d8f823 |
index 1baeba194794..7aad59376ff4 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
|
|
|
d8f823 |
@@ -1194,6 +1194,7 @@ void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
|
|
d8f823 |
struct mlx5e_priv *priv = netdev_priv(netdev);
|
|
|
d8f823 |
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
|
|
d8f823 |
struct mlx5_eswitch_rep *rep = rpriv->rep;
|
|
|
d8f823 |
+ struct mlx5e_tc_update_priv tc_priv = {};
|
|
|
d8f823 |
struct mlx5_wq_cyc *wq = &rq->wqe.wq;
|
|
|
d8f823 |
struct mlx5e_wqe_frag_info *wi;
|
|
|
d8f823 |
struct sk_buff *skb;
|
|
|
d8f823 |
@@ -1226,11 +1227,13 @@ void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
|
|
|
d8f823 |
if (rep->vlan && skb_vlan_tag_present(skb))
|
|
|
d8f823 |
skb_vlan_pop(skb);
|
|
|
d8f823 |
|
|
|
d8f823 |
- if (!mlx5e_tc_rep_update_skb(cqe, skb))
|
|
|
d8f823 |
+ if (!mlx5e_tc_rep_update_skb(cqe, skb, &tc_priv))
|
|
|
d8f823 |
goto free_wqe;
|
|
|
d8f823 |
|
|
|
d8f823 |
napi_gro_receive(rq->cq.napi, skb);
|
|
|
d8f823 |
|
|
|
d8f823 |
+ mlx5_tc_rep_post_napi_receive(&tc_priv);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
free_wqe:
|
|
|
d8f823 |
mlx5e_free_rx_wqe(rq, wi, true);
|
|
|
d8f823 |
wq_cyc_pop:
|
|
|
d8f823 |
@@ -1247,6 +1250,7 @@ void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq,
|
|
|
d8f823 |
u32 wqe_offset = stride_ix << rq->mpwqe.log_stride_sz;
|
|
|
d8f823 |
u32 head_offset = wqe_offset & (PAGE_SIZE - 1);
|
|
|
d8f823 |
u32 page_idx = wqe_offset >> PAGE_SHIFT;
|
|
|
d8f823 |
+ struct mlx5e_tc_update_priv tc_priv = {};
|
|
|
d8f823 |
struct mlx5e_rx_wqe_ll *wqe;
|
|
|
d8f823 |
struct mlx5_wq_ll *wq;
|
|
|
d8f823 |
struct sk_buff *skb;
|
|
|
d8f823 |
@@ -1279,11 +1283,13 @@ void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq,
|
|
|
d8f823 |
|
|
|
d8f823 |
mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb);
|
|
|
d8f823 |
|
|
|
d8f823 |
- if (!mlx5e_tc_rep_update_skb(cqe, skb))
|
|
|
d8f823 |
+ if (!mlx5e_tc_rep_update_skb(cqe, skb, &tc_priv))
|
|
|
d8f823 |
goto mpwrq_cqe_out;
|
|
|
d8f823 |
|
|
|
d8f823 |
napi_gro_receive(rq->cq.napi, skb);
|
|
|
d8f823 |
|
|
|
d8f823 |
+ mlx5_tc_rep_post_napi_receive(&tc_priv);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
mpwrq_cqe_out:
|
|
|
d8f823 |
if (likely(wi->consumed_strides < rq->mpwqe.num_strides))
|
|
|
d8f823 |
return;
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
index a7d3cca88718..269258c5f961 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
|
|
|
d8f823 |
@@ -4689,19 +4689,102 @@ void mlx5e_tc_reoffload_flows_work(struct work_struct *work)
|
|
|
d8f823 |
mutex_unlock(&rpriv->unready_flows_lock);
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
+#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
|
|
d8f823 |
+static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb,
|
|
|
d8f823 |
+ struct mlx5e_tc_update_priv *tc_priv,
|
|
|
d8f823 |
+ u32 tunnel_id)
|
|
|
d8f823 |
+{
|
|
|
d8f823 |
+ struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
|
|
d8f823 |
+ struct flow_dissector_key_enc_opts enc_opts = {};
|
|
|
d8f823 |
+ struct mlx5_rep_uplink_priv *uplink_priv;
|
|
|
d8f823 |
+ struct mlx5e_rep_priv *uplink_rpriv;
|
|
|
d8f823 |
+ struct metadata_dst *tun_dst;
|
|
|
d8f823 |
+ struct tunnel_match_key key;
|
|
|
d8f823 |
+ u32 tun_id, enc_opts_id;
|
|
|
d8f823 |
+ struct net_device *dev;
|
|
|
d8f823 |
+ int err;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ enc_opts_id = tunnel_id & ENC_OPTS_BITS_MASK;
|
|
|
d8f823 |
+ tun_id = tunnel_id >> ENC_OPTS_BITS;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ if (!tun_id)
|
|
|
d8f823 |
+ return true;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
|
|
|
d8f823 |
+ uplink_priv = &uplink_rpriv->uplink_priv;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ err = mapping_find(uplink_priv->tunnel_mapping, tun_id, &key);
|
|
|
d8f823 |
+ if (err) {
|
|
|
d8f823 |
+ WARN_ON_ONCE(true);
|
|
|
d8f823 |
+ netdev_dbg(priv->netdev,
|
|
|
d8f823 |
+ "Couldn't find tunnel for tun_id: %d, err: %d\n",
|
|
|
d8f823 |
+ tun_id, err);
|
|
|
d8f823 |
+ return false;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ if (enc_opts_id) {
|
|
|
d8f823 |
+ err = mapping_find(uplink_priv->tunnel_enc_opts_mapping,
|
|
|
d8f823 |
+ enc_opts_id, &enc_opts);
|
|
|
d8f823 |
+ if (err) {
|
|
|
d8f823 |
+ netdev_dbg(priv->netdev,
|
|
|
d8f823 |
+ "Couldn't find tunnel (opts) for tun_id: %d, err: %d\n",
|
|
|
d8f823 |
+ enc_opts_id, err);
|
|
|
d8f823 |
+ return false;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ tun_dst = tun_rx_dst(enc_opts.len);
|
|
|
d8f823 |
+ if (!tun_dst) {
|
|
|
d8f823 |
+ WARN_ON_ONCE(true);
|
|
|
d8f823 |
+ return false;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ ip_tunnel_key_init(&tun_dst->u.tun_info.key,
|
|
|
d8f823 |
+ key.enc_ipv4.src, key.enc_ipv4.dst,
|
|
|
d8f823 |
+ key.enc_ip.tos, key.enc_ip.ttl,
|
|
|
d8f823 |
+ 0, /* label */
|
|
|
d8f823 |
+ key.enc_tp.src, key.enc_tp.dst,
|
|
|
d8f823 |
+ key32_to_tunnel_id(key.enc_key_id.keyid),
|
|
|
d8f823 |
+ TUNNEL_KEY);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ if (enc_opts.len)
|
|
|
d8f823 |
+ ip_tunnel_info_opts_set(&tun_dst->u.tun_info, enc_opts.data,
|
|
|
d8f823 |
+ enc_opts.len, enc_opts.dst_opt_type);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ skb_dst_set(skb, (struct dst_entry *)tun_dst);
|
|
|
d8f823 |
+ dev = dev_get_by_index(&init_net, key.filter_ifindex);
|
|
|
d8f823 |
+ if (!dev) {
|
|
|
d8f823 |
+ netdev_dbg(priv->netdev,
|
|
|
d8f823 |
+ "Couldn't find tunnel device with ifindex: %d\n",
|
|
|
d8f823 |
+ key.filter_ifindex);
|
|
|
d8f823 |
+ return false;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ /* Set tun_dev so we do dev_put() after datapath */
|
|
|
d8f823 |
+ tc_priv->tun_dev = dev;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ skb->dev = dev;
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+ return true;
|
|
|
d8f823 |
+}
|
|
|
d8f823 |
+#endif /* CONFIG_NET_TC_SKB_EXT */
|
|
|
d8f823 |
+
|
|
|
d8f823 |
bool mlx5e_tc_rep_update_skb(struct mlx5_cqe64 *cqe,
|
|
|
d8f823 |
- struct sk_buff *skb)
|
|
|
d8f823 |
+ struct sk_buff *skb,
|
|
|
d8f823 |
+ struct mlx5e_tc_update_priv *tc_priv)
|
|
|
d8f823 |
{
|
|
|
d8f823 |
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
|
|
d8f823 |
+ u32 chain = 0, reg_c0, reg_c1, tunnel_id;
|
|
|
d8f823 |
struct tc_skb_ext *tc_skb_ext;
|
|
|
d8f823 |
struct mlx5_eswitch *esw;
|
|
|
d8f823 |
struct mlx5e_priv *priv;
|
|
|
d8f823 |
- u32 chain = 0, reg_c0;
|
|
|
d8f823 |
+ int tunnel_moffset;
|
|
|
d8f823 |
int err;
|
|
|
d8f823 |
|
|
|
d8f823 |
reg_c0 = (be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK);
|
|
|
d8f823 |
if (reg_c0 == MLX5_FS_DEFAULT_FLOW_TAG)
|
|
|
d8f823 |
reg_c0 = 0;
|
|
|
d8f823 |
+ reg_c1 = be32_to_cpu(cqe->imm_inval_pkey);
|
|
|
d8f823 |
|
|
|
d8f823 |
if (!reg_c0)
|
|
|
d8f823 |
return true;
|
|
|
d8f823 |
@@ -4717,17 +4800,26 @@ bool mlx5e_tc_rep_update_skb(struct mlx5_cqe64 *cqe,
|
|
|
d8f823 |
return false;
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
- if (!chain)
|
|
|
d8f823 |
- return true;
|
|
|
d8f823 |
+ if (chain) {
|
|
|
d8f823 |
+ tc_skb_ext = skb_ext_add(skb, TC_SKB_EXT);
|
|
|
d8f823 |
+ if (!tc_skb_ext) {
|
|
|
d8f823 |
+ WARN_ON(1);
|
|
|
d8f823 |
+ return false;
|
|
|
d8f823 |
+ }
|
|
|
d8f823 |
|
|
|
d8f823 |
- tc_skb_ext = skb_ext_add(skb, TC_SKB_EXT);
|
|
|
d8f823 |
- if (!tc_skb_ext) {
|
|
|
d8f823 |
- WARN_ON_ONCE(1);
|
|
|
d8f823 |
- return false;
|
|
|
d8f823 |
+ tc_skb_ext->chain = chain;
|
|
|
d8f823 |
}
|
|
|
d8f823 |
|
|
|
d8f823 |
- tc_skb_ext->chain = chain;
|
|
|
d8f823 |
+ tunnel_moffset = mlx5e_tc_attr_to_reg_mappings[TUNNEL_TO_REG].moffset;
|
|
|
d8f823 |
+ tunnel_id = reg_c1 >> (8 * tunnel_moffset);
|
|
|
d8f823 |
+ return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id);
|
|
|
d8f823 |
#endif /* CONFIG_NET_TC_SKB_EXT */
|
|
|
d8f823 |
|
|
|
d8f823 |
return true;
|
|
|
d8f823 |
}
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+void mlx5_tc_rep_post_napi_receive(struct mlx5e_tc_update_priv *tc_priv)
|
|
|
d8f823 |
+{
|
|
|
d8f823 |
+ if (tc_priv->tun_dev)
|
|
|
d8f823 |
+ dev_put(tc_priv->tun_dev);
|
|
|
d8f823 |
+}
|
|
|
d8f823 |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
index 2fab76b0bec5..21cbde472b64 100644
|
|
|
d8f823 |
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
|
|
|
d8f823 |
@@ -109,7 +109,14 @@ extern struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[];
|
|
|
d8f823 |
bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
|
|
|
d8f823 |
struct net_device *out_dev);
|
|
|
d8f823 |
|
|
|
d8f823 |
-bool mlx5e_tc_rep_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb);
|
|
|
d8f823 |
+struct mlx5e_tc_update_priv {
|
|
|
d8f823 |
+ struct net_device *tun_dev;
|
|
|
d8f823 |
+};
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+bool mlx5e_tc_rep_update_skb(struct mlx5_cqe64 *cqe, struct sk_buff *skb,
|
|
|
d8f823 |
+ struct mlx5e_tc_update_priv *tc_priv);
|
|
|
d8f823 |
+
|
|
|
d8f823 |
+void mlx5_tc_rep_post_napi_receive(struct mlx5e_tc_update_priv *tc_priv);
|
|
|
d8f823 |
|
|
|
d8f823 |
struct mlx5e_tc_mod_hdr_acts {
|
|
|
d8f823 |
int num_actions;
|
|
|
d8f823 |
--
|
|
|
d8f823 |
2.13.6
|
|
|
d8f823 |
|