Commit 39542e23 authored by Roi Dayan's avatar Roi Dayan Committed by Saeed Mahameed
Browse files

net/mlx5e: Move code chunk setting encap dests into its own function



Split setting encap dests code chunk out of mlx5e_tc_add_fdb_flow()
to make the function smaller for maintainability and reuse.
For symmetry do the same for mlx5e_tc_del_fdb_flow().
While at it refactor cleanup to first check for encap flag like
done when setting encap dests.

Signed-off-by: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarOz Shlomo <ozsh@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent e2cf0765
Loading
Loading
Loading
Loading
+93 −51
Original line number Diff line number Diff line
@@ -1367,6 +1367,94 @@ int mlx5e_tc_add_flow_mod_hdr(struct mlx5e_priv *priv,
	return 0;
}

static int
set_encap_dests(struct mlx5e_priv *priv,
		struct mlx5e_tc_flow *flow,
		struct netlink_ext_ack *extack,
		bool *encap_valid,
		bool *vf_tun)
{
	struct mlx5e_tc_flow_parse_attr *parse_attr;
	struct mlx5_flow_attr *attr = flow->attr;
	struct mlx5_esw_flow_attr *esw_attr;
	struct net_device *encap_dev = NULL;
	struct mlx5e_rep_priv *rpriv;
	struct mlx5e_priv *out_priv;
	int out_index;
	int err = 0;

	parse_attr = attr->parse_attr;
	esw_attr = attr->esw_attr;
	*vf_tun = false;
	*encap_valid = true;

	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
		struct net_device *out_dev;
		int mirred_ifindex;

		if (!(esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP))
			continue;

		mirred_ifindex = parse_attr->mirred_ifindex[out_index];
		out_dev = dev_get_by_index(dev_net(priv->netdev), mirred_ifindex);
		if (!out_dev) {
			NL_SET_ERR_MSG_MOD(extack, "Requested mirred device not found");
			err = -ENODEV;
			goto out;
		}
		err = mlx5e_attach_encap(priv, flow, out_dev, out_index,
					 extack, &encap_dev, encap_valid);
		dev_put(out_dev);
		if (err)
			goto out;

		if (esw_attr->dests[out_index].flags &
		    MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
		    !esw_attr->dest_int_port)
			*vf_tun = true;

		out_priv = netdev_priv(encap_dev);
		rpriv = out_priv->ppriv;
		esw_attr->dests[out_index].rep = rpriv->rep;
		esw_attr->dests[out_index].mdev = out_priv->mdev;
	}

	if (*vf_tun && esw_attr->out_count > 1) {
		NL_SET_ERR_MSG_MOD(extack, "VF tunnel encap with mirroring is not supported");
		err = -EOPNOTSUPP;
		goto out;
	}

out:
	return err;
}

static void
clean_encap_dests(struct mlx5e_priv *priv,
		  struct mlx5e_tc_flow *flow,
		  bool *vf_tun)
{
	struct mlx5_flow_attr *attr = flow->attr;
	struct mlx5_esw_flow_attr *esw_attr;
	int out_index;

	esw_attr = attr->esw_attr;
	*vf_tun = false;

	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
		if (!(esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP))
			continue;

		if (esw_attr->dests[out_index].flags &
		    MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
		    !esw_attr->dest_int_port)
			*vf_tun = true;

		mlx5e_detach_encap(priv, flow, out_index);
		kfree(attr->parse_attr->tun_info[out_index]);
	}
}

static int
mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
		      struct mlx5e_tc_flow *flow,
@@ -1375,15 +1463,11 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
	struct mlx5e_tc_flow_parse_attr *parse_attr;
	struct mlx5_flow_attr *attr = flow->attr;
	bool vf_tun = false, encap_valid = true;
	struct net_device *encap_dev = NULL;
	struct mlx5_esw_flow_attr *esw_attr;
	struct mlx5e_rep_priv *rpriv;
	struct mlx5e_priv *out_priv;
	bool vf_tun, encap_valid;
	struct mlx5_fc *counter;
	u32 max_prio, max_chain;
	int err = 0;
	int out_index;

	parse_attr = attr->parse_attr;
	esw_attr = attr->esw_attr;
@@ -1471,42 +1555,10 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
		esw_attr->int_port = int_port;
	}

	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
		struct net_device *out_dev;
		int mirred_ifindex;

		if (!(esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP))
			continue;

		mirred_ifindex = parse_attr->mirred_ifindex[out_index];
		out_dev = dev_get_by_index(dev_net(priv->netdev), mirred_ifindex);
		if (!out_dev) {
			NL_SET_ERR_MSG_MOD(extack, "Requested mirred device not found");
			err = -ENODEV;
			goto err_out;
		}
		err = mlx5e_attach_encap(priv, flow, out_dev, out_index,
					 extack, &encap_dev, &encap_valid);
		dev_put(out_dev);
	err = set_encap_dests(priv, flow, extack, &encap_valid, &vf_tun);
	if (err)
		goto err_out;

		if (esw_attr->dests[out_index].flags &
		    MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
		    !esw_attr->dest_int_port)
			vf_tun = true;
		out_priv = netdev_priv(encap_dev);
		rpriv = out_priv->ppriv;
		esw_attr->dests[out_index].rep = rpriv->rep;
		esw_attr->dests[out_index].mdev = out_priv->mdev;
	}

	if (vf_tun && esw_attr->out_count > 1) {
		NL_SET_ERR_MSG_MOD(extack, "VF tunnel encap with mirroring is not supported");
		err = -EOPNOTSUPP;
		goto err_out;
	}

	err = mlx5_eswitch_add_vlan_action(esw, attr);
	if (err)
		goto err_out;
@@ -1575,8 +1627,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
	struct mlx5_flow_attr *attr = flow->attr;
	struct mlx5_esw_flow_attr *esw_attr;
	bool vf_tun = false;
	int out_index;
	bool vf_tun;

	esw_attr = attr->esw_attr;
	mlx5e_put_flow_tunnel_id(flow);
@@ -1600,16 +1651,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
	if (flow->decap_route)
		mlx5e_detach_decap_route(priv, flow);

	for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
		if (esw_attr->dests[out_index].flags &
		    MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
		    !esw_attr->dest_int_port)
			vf_tun = true;
		if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) {
			mlx5e_detach_encap(priv, flow, out_index);
			kfree(attr->parse_attr->tun_info[out_index]);
		}
	}
	clean_encap_dests(priv, flow, &vf_tun);

	mlx5_tc_ct_match_del(get_ct_priv(priv), &flow->attr->ct_attr);