From: Valentine Fatiev <valentinef@nvidia.com>
Subject: [PATCH] BACKPORT:
 drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c

Change-Id: I0dcbcb5f01e44769110675bf0e156beea0a55759
---
 .../mellanox/mlx5/core/en/tc_tun_vxlan.c      | 88 +++++++++++++++++--
 1 file changed, 83 insertions(+), 5 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c
@@ -18,9 +18,12 @@ static int mlx5e_tc_tun_calc_hlen_vxlan(
 
 static int mlx5e_tc_tun_check_udp_dport_vxlan(struct mlx5e_priv *priv,
 					      struct flow_cls_offload *f)
+
 {
 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
-	struct netlink_ext_ack *extack = f->common.extack;
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
+       struct netlink_ext_ack *extack = f->common.extack;
+#endif
 	struct flow_match_ports enc_ports;
 
 	if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS))
@@ -32,8 +35,10 @@ static int mlx5e_tc_tun_check_udp_dport_
 
 	if (!mlx5_vxlan_lookup_port(priv->mdev->vxlan,
 				    be16_to_cpu(enc_ports.key->dst))) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack,
 				   "Matched UDP dst port is not registered as a VXLAN port");
+#endif
 		netdev_warn(priv->netdev,
 			    "UDP port %d is not registered as a VXLAN port\n",
 			    be16_to_cpu(enc_ports.key->dst));
@@ -68,8 +73,10 @@ static int mlx5e_tc_tun_init_encap_attr_
 	e->tunnel = &vxlan_tunnel;
 
 	if (!mlx5_vxlan_lookup_port(priv->mdev->vxlan, dst_port)) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack,
 				   "vxlan udp dport was not registered with the HW");
+#endif
 		netdev_warn(priv->netdev,
 			    "%d isn't an offloaded vxlan udp dport\n",
 			    dst_port);
@@ -80,6 +87,31 @@ static int mlx5e_tc_tun_init_encap_attr_
 	return 0;
 }
 
+#ifndef HAVE_CHECK_VXLAN_BUILD_GBP_HDR
+static void vxlan_build_gbp_hdr(struct vxlanhdr *vxh, struct vxlan_metadata *md)
+{
+	struct vxlanhdr_gbp *gbp;
+
+	if (!md->gbp)
+		return;
+
+	gbp = (struct vxlanhdr_gbp *)vxh;
+	vxh->vx_flags |= VXLAN_HF_GBP;
+
+	if (md->gbp & VXLAN_GBP_DONT_LEARN)
+		gbp->dont_learn = 1;
+
+	if (md->gbp & VXLAN_GBP_POLICY_APPLIED)
+		gbp->policy_applied = 1;
+
+	gbp->policy_id = htons(md->gbp & VXLAN_GBP_ID_MASK);
+}
+#endif
+#ifndef HAVE_CHECK_VXLAN_GBP_MASK
+#define VXLAN_GBP_MASK (VXLAN_GBP_DONT_LEARN | VXLAN_GBP_POLICY_APPLIED | \
+			VXLAN_GBP_ID_MASK)
+#endif
+
 static int mlx5e_gen_ip_tunnel_header_vxlan(char buf[],
 					    __u8 *ip_proto,
 					    struct mlx5e_encap_entry *e)
@@ -90,7 +122,11 @@ static int mlx5e_gen_ip_tunnel_header_vx
 	const struct vxlan_metadata *md;
 	struct vxlanhdr *vxh;
 
+#ifdef HAVE_CONVERT_BE16_TUNNEL_FLAGS_TO_BITMAPS //forwardport
+	if (test_bit(IP_TUNNEL_VXLAN_OPT_BIT, tun_key->tun_flags) &&
+#else
 	if ((tun_key->tun_flags & TUNNEL_VXLAN_OPT) &&
+#endif
 	    e->tun_info->options_len != sizeof(*md))
 		return -EOPNOTSUPP;
 	vxh = (struct vxlanhdr *)((char *)udp + sizeof(struct udphdr));
@@ -99,9 +135,13 @@ static int mlx5e_gen_ip_tunnel_header_vx
 	udp->dest = tun_key->tp_dst;
 	vxh->vx_flags = VXLAN_HF_VNI;
 	vxh->vx_vni = vxlan_vni_field(tun_id);
+#ifdef HAVE_CONVERT_BE16_TUNNEL_FLAGS_TO_BITMAPS //forwardport
+	if (test_bit(IP_TUNNEL_VXLAN_OPT_BIT, tun_key->tun_flags)) {
+#else
 	if (tun_key->tun_flags & TUNNEL_VXLAN_OPT) {
-		md = ip_tunnel_info_opts(e->tun_info);
-		vxlan_build_gbp_hdr(vxh, md);
+#endif
+		md = ip_tunnel_info_opts((struct ip_tunnel_info *)e->tun_info);
+		vxlan_build_gbp_hdr(vxh, (struct vxlan_metadata *)md);
 	}
 
 	return 0;
@@ -112,7 +152,9 @@ static int mlx5e_tc_tun_parse_vxlan_gbp_
 					       struct flow_cls_offload *f)
 {
 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 	struct netlink_ext_ack *extack = f->common.extack;
+#endif
 	struct flow_match_enc_opts enc_opts;
 	void *misc5_c, *misc5_v;
 	u32 *gbp, *gbp_mask;
@@ -120,19 +162,29 @@ static int mlx5e_tc_tun_parse_vxlan_gbp_
 	flow_rule_match_enc_opts(rule, &enc_opts);
 
 	if (memchr_inv(&enc_opts.mask->data, 0, sizeof(enc_opts.mask->data)) &&
-	    !MLX5_CAP_ESW_FT_FIELD_SUPPORT_2(priv->mdev, tunnel_header_0_1)) {
+			!MLX5_CAP_ESW_FT_FIELD_SUPPORT_2(priv->mdev, tunnel_header_0_1)) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack, "Matching on VxLAN GBP is not supported");
+#endif
 		return -EOPNOTSUPP;
 	}
 
+#ifdef HAVE_CONVERT_BE16_TUNNEL_FLAGS_TO_BITMAPS //forwardport
+	if (enc_opts.key->dst_opt_type != IP_TUNNEL_VXLAN_OPT_BIT) {
+#else
 	if (enc_opts.key->dst_opt_type != TUNNEL_VXLAN_OPT) {
+#endif
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack, "Wrong VxLAN option type: not GBP");
+#endif
 		return -EOPNOTSUPP;
 	}
 
 	if (enc_opts.key->len != sizeof(*gbp) ||
-	    enc_opts.mask->len != sizeof(*gbp_mask)) {
+			enc_opts.mask->len != sizeof(*gbp_mask)) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack, "VxLAN GBP option/mask len is not 32 bits");
+#endif
 		return -EINVAL;
 	}
 
@@ -140,7 +192,13 @@ static int mlx5e_tc_tun_parse_vxlan_gbp_
 	gbp_mask = (u32 *)&enc_opts.mask->data[0];
 
 	if (*gbp_mask & ~VXLAN_GBP_MASK) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
+#ifdef NL_SET_ERR_MSG_FMT_MOD
 		NL_SET_ERR_MSG_FMT_MOD(extack, "Wrong VxLAN GBP mask(0x%08X)\n", *gbp_mask);
+#else
+		NL_SET_ERR_MSG_MOD(extack, "Wrong VxLAN GBP mask\n");
+#endif
+#endif
 		return -EINVAL;
 	}
 
@@ -161,7 +219,9 @@ static int mlx5e_tc_tun_parse_vxlan(stru
 				    void *headers_v)
 {
 	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 	struct netlink_ext_ack *extack = f->common.extack;
+#endif
 	struct flow_match_enc_keyid enc_keyid;
 	void *misc_c, *misc_v;
 
@@ -188,8 +248,10 @@ static int mlx5e_tc_tun_parse_vxlan(stru
 
 	if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
 					ft_field_support.outer_vxlan_vni)) {
+#ifdef HAVE_TC_CLS_OFFLOAD_EXTACK
 		NL_SET_ERR_MSG_MOD(extack,
 				   "Matching on VXLAN VNI is not supported");
+#endif
 		netdev_warn(priv->netdev,
 			    "Matching on VXLAN VNI is not supported\n");
 		return -EOPNOTSUPP;
@@ -208,13 +270,29 @@ static int mlx5e_tc_tun_parse_vxlan(stru
 static bool mlx5e_tc_tun_encap_info_equal_vxlan(struct mlx5e_encap_key *a,
 						struct mlx5e_encap_key *b)
 {
+#ifdef HAVE_CONVERT_BE16_TUNNEL_FLAGS_TO_BITMAPS //forwardport
+	return mlx5e_tc_tun_encap_info_equal_options(a, b,
+						     IP_TUNNEL_VXLAN_OPT_BIT);
+#else
 	return mlx5e_tc_tun_encap_info_equal_options(a, b, TUNNEL_VXLAN_OPT);
+#endif
 }
 
 static int mlx5e_tc_tun_get_remote_ifindex(struct net_device *mirred_dev)
 {
 	const struct vxlan_dev *vxlan = netdev_priv(mirred_dev);
 	const struct vxlan_rdst *dst = &vxlan->default_dst;
+#ifdef HAVE_BASECODE_EXTRAS
+	int i;
+
+	for (i = 0; i < 5; i++) {
+		if ((int) dst->remote_ifindex >= 0)
+			break;
+		msleep(1);
+	}
+	if ((int) dst->remote_ifindex < 0)
+		return 0;
+#endif
 
 	return dst->remote_ifindex;
 }
