Commit 7e6a95d3 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-act_police-offload-support'



Jakub Kicinski says:

===================
net: act_police offload support

this set starts by converting cls_matchall to the new flow offload
infrastructure. It so happens that all drivers implementing cls_matchall
offload today also offload cls_flower, so its a little easier for
them to handle the actions in unified flow_rule format, even though
in cls_matchall there is no flow to speak of. If a driver ever appears
which would prefer the old, direct access to TC exts, we can add the
pointer in the offload structure back and support both.

Next the act_police is added to actions supported by flow offload API.

NFP support for act_police offload is added as the final step.  The flower
firmware is configured to perform TX rate limiting in a way which matches
act_police's behaviour.  It does not use DMA.IN back pressure, and
instead	drops packets after they had been already DMAed into the NIC.
IOW it uses our standard traffic policing implementation, future patches
will extend it to other ports and traffic directions.
===================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c8f8207c 5fb5c395
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -1269,21 +1269,19 @@ mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port,
static int
mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
				      struct mlxsw_sp_port_mall_mirror_tc_entry *mirror,
				      const struct tc_action *a,
				      const struct flow_action_entry *act,
				      bool ingress)
{
	enum mlxsw_sp_span_type span_type;
	struct net_device *to_dev;

	to_dev = tcf_mirred_dev(a);
	if (!to_dev) {
	if (!act->dev) {
		netdev_err(mlxsw_sp_port->dev, "Could not find requested device\n");
		return -EINVAL;
	}

	mirror->ingress = ingress;
	span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
	return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_dev, span_type,
	return mlxsw_sp_span_mirror_add(mlxsw_sp_port, act->dev, span_type,
					true, &mirror->span_id);
}

@@ -1302,7 +1300,7 @@ mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
static int
mlxsw_sp_port_add_cls_matchall_sample(struct mlxsw_sp_port *mlxsw_sp_port,
				      struct tc_cls_matchall_offload *cls,
				      const struct tc_action *a,
				      const struct flow_action_entry *act,
				      bool ingress)
{
	int err;
@@ -1313,18 +1311,18 @@ mlxsw_sp_port_add_cls_matchall_sample(struct mlxsw_sp_port *mlxsw_sp_port,
		netdev_err(mlxsw_sp_port->dev, "sample already active\n");
		return -EEXIST;
	}
	if (tcf_sample_rate(a) > MLXSW_REG_MPSC_RATE_MAX) {
	if (act->sample.rate > MLXSW_REG_MPSC_RATE_MAX) {
		netdev_err(mlxsw_sp_port->dev, "sample rate not supported\n");
		return -EOPNOTSUPP;
	}

	rcu_assign_pointer(mlxsw_sp_port->sample->psample_group,
			   tcf_sample_psample_group(a));
	mlxsw_sp_port->sample->truncate = tcf_sample_truncate(a);
	mlxsw_sp_port->sample->trunc_size = tcf_sample_trunc_size(a);
	mlxsw_sp_port->sample->rate = tcf_sample_rate(a);
			   act->sample.psample_group);
	mlxsw_sp_port->sample->truncate = act->sample.truncate;
	mlxsw_sp_port->sample->trunc_size = act->sample.trunc_size;
	mlxsw_sp_port->sample->rate = act->sample.rate;

	err = mlxsw_sp_port_sample_set(mlxsw_sp_port, true, tcf_sample_rate(a));
	err = mlxsw_sp_port_sample_set(mlxsw_sp_port, true, act->sample.rate);
	if (err)
		goto err_port_sample_set;
	return 0;
@@ -1350,10 +1348,10 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
{
	struct mlxsw_sp_port_mall_tc_entry *mall_tc_entry;
	__be16 protocol = f->common.protocol;
	const struct tc_action *a;
	struct flow_action_entry *act;
	int err;

	if (!tcf_exts_has_one_action(f->exts)) {
	if (!flow_offload_has_one_action(&f->rule->action)) {
		netdev_err(mlxsw_sp_port->dev, "only singular actions are supported\n");
		return -EOPNOTSUPP;
	}
@@ -1363,19 +1361,21 @@ static int mlxsw_sp_port_add_cls_matchall(struct mlxsw_sp_port *mlxsw_sp_port,
		return -ENOMEM;
	mall_tc_entry->cookie = f->cookie;

	a = tcf_exts_first_action(f->exts);
	act = &f->rule->action.entries[0];

	if (is_tcf_mirred_egress_mirror(a) && protocol == htons(ETH_P_ALL)) {
	if (act->id == FLOW_ACTION_MIRRED && protocol == htons(ETH_P_ALL)) {
		struct mlxsw_sp_port_mall_mirror_tc_entry *mirror;

		mall_tc_entry->type = MLXSW_SP_PORT_MALL_MIRROR;
		mirror = &mall_tc_entry->mirror;
		err = mlxsw_sp_port_add_cls_matchall_mirror(mlxsw_sp_port,
							    mirror, a, ingress);
	} else if (is_tcf_sample(a) && protocol == htons(ETH_P_ALL)) {
							    mirror, act,
							    ingress);
	} else if (act->id == FLOW_ACTION_SAMPLE &&
		   protocol == htons(ETH_P_ALL)) {
		mall_tc_entry->type = MLXSW_SP_PORT_MALL_SAMPLE;
		err = mlxsw_sp_port_add_cls_matchall_sample(mlxsw_sp_port, f,
							    a, ingress);
							    act, ingress);
	} else {
		err = -EOPNOTSUPP;
	}
+2 −1
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ nfp-objs += \
	    flower/match.o \
	    flower/metadata.o \
	    flower/offload.o \
	    flower/tunnel_conf.o
	    flower/tunnel_conf.o \
	    flower/qos_conf.o
endif

ifeq ($(CONFIG_BPF_SYSCALL),y)
+3 −0
Original line number Diff line number Diff line
@@ -278,6 +278,9 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
	case NFP_FLOWER_CMSG_TYPE_ACTIVE_TUNS:
		nfp_tunnel_keep_alive(app, skb);
		break;
	case NFP_FLOWER_CMSG_TYPE_QOS_STATS:
		nfp_flower_stats_rlim_reply(app, skb);
		break;
	case NFP_FLOWER_CMSG_TYPE_LAG_CONFIG:
		if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG) {
			skb_stored = nfp_flower_lag_unprocessed_msg(app, skb);
+3 −0
Original line number Diff line number Diff line
@@ -416,6 +416,9 @@ enum nfp_flower_cmsg_type_port {
	NFP_FLOWER_CMSG_TYPE_TUN_IPS =		14,
	NFP_FLOWER_CMSG_TYPE_FLOW_STATS =	15,
	NFP_FLOWER_CMSG_TYPE_PORT_ECHO =	16,
	NFP_FLOWER_CMSG_TYPE_QOS_MOD =		18,
	NFP_FLOWER_CMSG_TYPE_QOS_DEL =		19,
	NFP_FLOWER_CMSG_TYPE_QOS_STATS =	20,
	NFP_FLOWER_CMSG_TYPE_MAX =		32,
};

+6 −0
Original line number Diff line number Diff line
@@ -776,6 +776,9 @@ static int nfp_flower_init(struct nfp_app *app)
		nfp_warn(app->cpp, "Flow mod/merge not supported by FW.\n");
	}

	if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
		nfp_flower_qos_init(app);

	INIT_LIST_HEAD(&app_priv->indr_block_cb_priv);
	INIT_LIST_HEAD(&app_priv->non_repr_priv);

@@ -799,6 +802,9 @@ static void nfp_flower_clean(struct nfp_app *app)
	skb_queue_purge(&app_priv->cmsg_skbs_low);
	flush_work(&app_priv->cmsg_work);

	if (app_priv->flower_ext_feats & NFP_FL_FEATS_VF_RLIM)
		nfp_flower_qos_cleanup(app);

	if (app_priv->flower_ext_feats & NFP_FL_FEATS_LAG)
		nfp_flower_lag_cleanup(&app_priv->nfp_lag);

Loading