From a021f5288acb2261683c6e044b2a3729963ee62d Mon Sep 17 00:00:00 2001 From: Alaa Hleihel Date: Mon, 1 Jun 2020 15:40:52 -0400 Subject: [PATCH 297/312] [netdrv] net/mlx5e: Allow partial data mask for tunnel options Message-id: <20200601154102.25980-30-ahleihel@redhat.com> Patchwork-id: 315734 Patchwork-instance: patchwork O-Subject: [RHEL8.3 BZ 1842258 29/39] net/mlx5e: Allow partial data mask for tunnel options Bugzilla: 1842258 RH-Acked-by: Honggang Li RH-Acked-by: Kamal Heib RH-Acked-by: Marcelo Leitner RH-Acked-by: Jarod Wilson Bugzilla: http://bugzilla.redhat.com/1842258 Upstream: git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git , branch: master commit d7a42ad062cc6b20b2c2a8c09dc61df2d4f5751f Author: Roi Dayan Date: Wed Mar 25 11:32:56 2020 +0200 net/mlx5e: Allow partial data mask for tunnel options We use mapping to save and restore the tunnel options. Save also the tunnel options mask. Signed-off-by: Roi Dayan Reviewed-by: Paul Blakey Signed-off-by: Saeed Mahameed Signed-off-by: Alaa Hleihel Signed-off-by: Frantisek Hrbata --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 32 +++++++++++++++++-------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index bc8878b82078..9ee982366893 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -171,6 +171,11 @@ struct tunnel_match_key { int filter_ifindex; }; +struct tunnel_match_enc_opts { + struct flow_dissector_key_enc_opts key; + struct flow_dissector_key_enc_opts mask; +}; + /* Tunnel_id mapping is TUNNEL_INFO_BITS + ENC_OPTS_BITS. * Upper TUNNEL_INFO_BITS for general tunnel info. * Lower ENC_OPTS_BITS bits for enc_opts. @@ -1824,9 +1829,7 @@ enc_opts_is_dont_care_or_full_match(struct mlx5e_priv *priv, *dont_care = false; if (opt->opt_class != U16_MAX || - opt->type != U8_MAX || - memchr_inv(opt->opt_data, 0xFF, - opt->length * 4)) { + opt->type != U8_MAX) { NL_SET_ERR_MSG(extack, "Partial match of tunnel options in chain > 0 isn't supported"); netdev_warn(priv->netdev, @@ -1863,6 +1866,7 @@ static int mlx5e_get_flow_tunnel_id(struct mlx5e_priv *priv, struct mlx5_esw_flow_attr *attr = flow->esw_attr; struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts; struct flow_match_enc_opts enc_opts_match; + struct tunnel_match_enc_opts tun_enc_opts; struct mlx5_rep_uplink_priv *uplink_priv; struct mlx5e_rep_priv *uplink_rpriv; struct tunnel_match_key tunnel_key; @@ -1905,8 +1909,14 @@ static int mlx5e_get_flow_tunnel_id(struct mlx5e_priv *priv, goto err_enc_opts; if (!enc_opts_is_dont_care) { + memset(&tun_enc_opts, 0, sizeof(tun_enc_opts)); + memcpy(&tun_enc_opts.key, enc_opts_match.key, + sizeof(*enc_opts_match.key)); + memcpy(&tun_enc_opts.mask, enc_opts_match.mask, + sizeof(*enc_opts_match.mask)); + err = mapping_add(uplink_priv->tunnel_enc_opts_mapping, - enc_opts_match.key, &enc_opts_id); + &tun_enc_opts, &enc_opts_id); if (err) goto err_enc_opts; } @@ -4691,7 +4701,7 @@ void mlx5e_tc_nic_cleanup(struct mlx5e_priv *priv) int mlx5e_tc_esw_init(struct rhashtable *tc_ht) { - const size_t sz_enc_opts = sizeof(struct flow_dissector_key_enc_opts); + const size_t sz_enc_opts = sizeof(struct tunnel_match_enc_opts); struct mlx5_rep_uplink_priv *uplink_priv; struct mlx5e_rep_priv *priv; struct mapping_ctx *mapping; @@ -4786,7 +4796,7 @@ static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb, u32 tunnel_id) { struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; - struct flow_dissector_key_enc_opts enc_opts = {}; + 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; @@ -4824,7 +4834,7 @@ static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb, } } - tun_dst = tun_rx_dst(enc_opts.len); + tun_dst = tun_rx_dst(enc_opts.key.len); if (!tun_dst) { WARN_ON_ONCE(true); return false; @@ -4838,9 +4848,11 @@ static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb, key32_to_tunnel_id(key.enc_key_id.keyid), TUNNEL_KEY); - if (enc_opts.len) - ip_tunnel_info_opts_set(&tun_dst->u.tun_info, enc_opts.data, - enc_opts.len, enc_opts.dst_opt_type); + 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); -- 2.13.6