Commit 79e28519 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5-updates-2020-03-17' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5-updates-2020-03-17

1) Compiler warnings and cleanup for the connection tracking series
2) Bug fixes for the connection tracking series
3) Fix devlink port register sequence
4) Last five patches in the series, By Eli cohen
   Add the support for forwarding traffic between two eswitch uplink
   representors (Hairpin for eswitch), using mlx5 termination tables
   to change the direction of a packet in hw from RX to TX pipeline.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d445dff2 87b51810
Loading
Loading
Loading
Loading
+10 −16
Original line number Diff line number Diff line
@@ -3,20 +3,14 @@

#include "en/devlink.h"

int mlx5e_devlink_port_register(struct net_device *netdev)
int mlx5e_devlink_port_register(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *dev;
	struct mlx5e_priv *priv;
	struct devlink *devlink;
	int err;
	struct devlink *devlink = priv_to_devlink(priv->mdev);

	priv = netdev_priv(netdev);
	dev = priv->mdev;

	if (mlx5_core_is_pf(dev))
	if (mlx5_core_is_pf(priv->mdev))
		devlink_port_attrs_set(&priv->dl_port,
				       DEVLINK_PORT_FLAVOUR_PHYSICAL,
				       PCI_FUNC(dev->pdev->devfn),
				       PCI_FUNC(priv->mdev->pdev->devfn),
				       false, 0,
				       NULL, 0);
	else
@@ -24,12 +18,12 @@ int mlx5e_devlink_port_register(struct net_device *netdev)
				       DEVLINK_PORT_FLAVOUR_VIRTUAL,
				       0, false, 0, NULL, 0);

	devlink = priv_to_devlink(dev);
	err = devlink_port_register(devlink, &priv->dl_port, 1);
	if (err)
		return err;
	devlink_port_type_eth_set(&priv->dl_port, netdev);
	return 0;
	return devlink_port_register(devlink, &priv->dl_port, 1);
}

void mlx5e_devlink_port_type_eth_set(struct mlx5e_priv *priv)
{
	devlink_port_type_eth_set(&priv->dl_port, priv->netdev);
}

void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv)
+2 −1
Original line number Diff line number Diff line
@@ -7,8 +7,9 @@
#include <net/devlink.h>
#include "en.h"

int mlx5e_devlink_port_register(struct net_device *dev);
int mlx5e_devlink_port_register(struct mlx5e_priv *priv);
void mlx5e_devlink_port_unregister(struct mlx5e_priv *priv);
void mlx5e_devlink_port_type_eth_set(struct mlx5e_priv *priv);
struct devlink_port *mlx5e_get_devlink_port(struct net_device *dev);

#endif
+23 −11
Original line number Diff line number Diff line
@@ -484,19 +484,23 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
	struct mlx5_ct_zone_rule *zone_rule = &entry->zone_rules[nat];
	struct mlx5_esw_flow_attr *attr = &zone_rule->attr;
	struct mlx5_eswitch *esw = ct_priv->esw;
	struct mlx5_flow_spec spec = {};
	struct mlx5_flow_spec *spec = NULL;
	u32 tupleid = 1;
	int err;

	zone_rule->nat = nat;

	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec)
		return -ENOMEM;

	/* Get tuple unique id */
	err = idr_alloc_u32(&ct_priv->tuple_ids, zone_rule, &tupleid,
			    TUPLE_ID_MAX, GFP_KERNEL);
	if (err) {
		netdev_warn(ct_priv->netdev,
			    "Failed to allocate tuple id, err: %d\n", err);
		return err;
		goto err_idr_alloc;
	}
	zone_rule->tupleid = tupleid;

@@ -517,18 +521,19 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv,
	attr->counter = entry->counter;
	attr->flags |= MLX5_ESW_ATTR_FLAG_NO_IN_PORT;

	mlx5_tc_ct_set_tuple_match(&spec, flow_rule);
	mlx5e_tc_match_to_reg_match(&spec, ZONE_TO_REG,
	mlx5_tc_ct_set_tuple_match(spec, flow_rule);
	mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG,
				    entry->zone & MLX5_CT_ZONE_MASK,
				    MLX5_CT_ZONE_MASK);

	zone_rule->rule = mlx5_eswitch_add_offloaded_rule(esw, &spec, attr);
	zone_rule->rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
	if (IS_ERR(zone_rule->rule)) {
		err = PTR_ERR(zone_rule->rule);
		ct_dbg("Failed to add ct entry rule, nat: %d", nat);
		goto err_rule;
	}

	kfree(spec);
	ct_dbg("Offloaded ct entry rule in zone %d", entry->zone);

	return 0;
@@ -537,6 +542,8 @@ err_rule:
	mlx5_modify_header_dealloc(esw->dev, attr->modify_hdr);
err_mod_hdr:
	idr_remove(&ct_priv->tuple_ids, zone_rule->tupleid);
err_idr_alloc:
	kfree(spec);
	return err;
}

@@ -696,7 +703,7 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
{
	struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
	struct flow_dissector_key_ct *mask, *key;
	bool trk, est, untrk, unest, new, unnew;
	bool trk, est, untrk, unest, new;
	u32 ctstate = 0, ctstate_mask = 0;
	u16 ct_state_on, ct_state_off;
	u16 ct_state, ct_state_mask;
@@ -739,7 +746,6 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
	new = ct_state_on & TCA_FLOWER_KEY_CT_FLAGS_NEW;
	est = ct_state_on & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;
	untrk = ct_state_off & TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
	unnew = ct_state_off & TCA_FLOWER_KEY_CT_FLAGS_NEW;
	unest = ct_state_off & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;

	ctstate |= trk ? MLX5_CT_STATE_TRK_BIT : 0;
@@ -885,8 +891,8 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
	struct mlx5_tc_ct_priv *ct_priv = mlx5_tc_ct_get_ct_priv(priv);
	bool nat = attr->ct_attr.ct_action & TCA_CT_ACT_NAT;
	struct mlx5e_tc_mod_hdr_acts pre_mod_acts = {};
	struct mlx5_flow_spec *post_ct_spec = NULL;
	struct mlx5_eswitch *esw = ct_priv->esw;
	struct mlx5_flow_spec post_ct_spec = {};
	struct mlx5_esw_flow_attr *pre_ct_attr;
	struct  mlx5_modify_hdr *mod_hdr;
	struct mlx5_flow_handle *rule;
@@ -895,9 +901,13 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
	struct mlx5_ct_ft *ft;
	u32 fte_id = 1;

	post_ct_spec = kzalloc(sizeof(*post_ct_spec), GFP_KERNEL);
	ct_flow = kzalloc(sizeof(*ct_flow), GFP_KERNEL);
	if (!ct_flow)
	if (!post_ct_spec || !ct_flow) {
		kfree(post_ct_spec);
		kfree(ct_flow);
		return -ENOMEM;
	}

	/* Register for CT established events */
	ft = mlx5_tc_ct_add_ft_cb(ct_priv, attr->ct_attr.zone,
@@ -992,7 +1002,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
	/* Post ct rule matches on fte_id and executes original rule's
	 * tc rule action
	 */
	mlx5e_tc_match_to_reg_match(&post_ct_spec, FTEID_TO_REG,
	mlx5e_tc_match_to_reg_match(post_ct_spec, FTEID_TO_REG,
				    fte_id, MLX5_FTE_ID_MASK);

	/* Put post_ct rule on post_ct fdb */
@@ -1003,7 +1013,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
	ct_flow->post_ct_attr.inner_match_level = MLX5_MATCH_NONE;
	ct_flow->post_ct_attr.outer_match_level = MLX5_MATCH_NONE;
	ct_flow->post_ct_attr.action &= ~(MLX5_FLOW_CONTEXT_ACTION_DECAP);
	rule = mlx5_eswitch_add_offloaded_rule(esw, &post_ct_spec,
	rule = mlx5_eswitch_add_offloaded_rule(esw, post_ct_spec,
					       &ct_flow->post_ct_attr);
	ct_flow->post_ct_rule = rule;
	if (IS_ERR(ct_flow->post_ct_rule)) {
@@ -1027,6 +1037,7 @@ __mlx5_tc_ct_flow_offload(struct mlx5e_priv *priv,
	attr->ct_attr.ct_flow = ct_flow;
	*flow_rule = ct_flow->post_ct_rule;
	dealloc_mod_hdr_actions(&pre_mod_acts);
	kfree(post_ct_spec);

	return 0;

@@ -1043,6 +1054,7 @@ err_get_chain:
err_idr:
	mlx5_tc_ct_del_ft_cb(ct_priv, ft);
err_ft:
	kfree(post_ct_spec);
	kfree(ct_flow);
	netdev_warn(priv->netdev, "Failed to offload ct flow, err %d\n", err);
	return err;
+9 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@
#include <linux/mlx5/fs.h>
#include <net/tc_act/tc_ct.h>

#include "en.h"

struct mlx5_esw_flow_attr;
struct mlx5e_tc_mod_hdr_acts;
struct mlx5_rep_uplink_priv;
@@ -128,6 +130,11 @@ mlx5_tc_ct_parse_match(struct mlx5e_priv *priv,
		       struct flow_cls_offload *f,
		       struct netlink_ext_ack *extack)
{
	if (!flow_rule_match_key(f->rule, FLOW_DISSECTOR_KEY_CT))
		return 0;

	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
	netdev_warn(priv->netdev, "mlx5 tc ct offload isn't enabled.\n");
	return -EOPNOTSUPP;
}

@@ -137,6 +144,8 @@ mlx5_tc_ct_parse_action(struct mlx5e_priv *priv,
			const struct flow_action_entry *act,
			struct netlink_ext_ack *extack)
{
	NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled.");
	netdev_warn(priv->netdev, "mlx5 tc ct offload isn't enabled.\n");
	return -EOPNOTSUPP;
}

+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
	      mlx5e_is_uplink_rep(netdev_priv(*out_dev))))
		return -EOPNOTSUPP;

	if (mlx5e_eswitch_uplink_rep(priv->netdev) && *out_dev != priv->netdev)
		return -EOPNOTSUPP;

	return 0;
}

Loading