History

Merge branch 'flow_offload-tc-police-parameters'

Jianbo Liu says: ==================== flow_offload: add tc police parameters As a preparation for more advanced police offload in mlx5 (e.g., jumping to another chain when bandwidth is not exceeded), extend the flow offload API with more tc-police parameters. Adjust existing drivers to reject unsupported configurations. Changes since v2: * Rename index to extval in exceed and notexceed acts. * Add policer validate functions for all drivers. Changes since v1: * Add one more strict validation for the control of drop/ok. ====================

David S. Miller committed 4 years ago

Commit c4eb0582 parents b42a738 d97b4b114 files · +454 −38Browse files

Unified · Split

14 files
  1. drivers/net/dsa/sja1105/sja1105_flower.c +42 −5
  2. drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c +49 −10
  3. drivers/net/ethernet/freescale/enetc/enetc_qos.c +43 −4
  4. drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +43 −0
  5. drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +44 −4
  6. drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +43 −4
  7. drivers/net/ethernet/mscc/ocelot_flower.c +8 −6
  8. drivers/net/ethernet/mscc/ocelot_net.c +5 −5
  9. drivers/net/ethernet/mscc/ocelot_police.c +41 −0
  10. drivers/net/ethernet/mscc/ocelot_police.h +5 −0
  11. drivers/net/ethernet/netronome/nfp/flower/qos_conf.c +40 −0
  12. include/net/flow_offload.h +15 −0
  13. include/net/tc_act/tc_police.h +30 −0
  14. net/sched/act_police.c +46 −0
drivers/net/dsa/sja1105/sja1105_flower.c+42−5
@@ -300,6 +300,46 @@ static int sja1105_flower_parse_key(struct sja1105_private *priv, · 299 unmodified lines
300300 return -EOPNOTSUPP;
301301 }
302302
303+static int sja1105_policer_validate(const struct flow_action *action,
304+ const struct flow_action_entry *act,
305+ struct netlink_ext_ack *extack)
306+{
307+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
308+ NL_SET_ERR_MSG_MOD(extack,
309+ "Offload not supported when exceed action is not drop");
310+ return -EOPNOTSUPP;
311+ }
312+
313+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
314+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
315+ NL_SET_ERR_MSG_MOD(extack,
316+ "Offload not supported when conform action is not pipe or ok");
317+ return -EOPNOTSUPP;
318+ }
319+
320+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
321+ !flow_action_is_last_entry(action, act)) {
322+ NL_SET_ERR_MSG_MOD(extack,
323+ "Offload not supported when conform action is ok, but action is not last");
324+ return -EOPNOTSUPP;
325+ }
326+
327+ if (act->police.peakrate_bytes_ps ||
328+ act->police.avrate || act->police.overhead) {
329+ NL_SET_ERR_MSG_MOD(extack,
330+ "Offload not supported when peakrate/avrate/overhead is configured");
331+ return -EOPNOTSUPP;
332+ }
333+
334+ if (act->police.rate_pkt_ps) {
335+ NL_SET_ERR_MSG_MOD(extack,
336+ "QoS offload not support packets per second");
337+ return -EOPNOTSUPP;
338+ }
339+
340+ return 0;
341+}
342+
303343 int sja1105_cls_flower_add(struct dsa_switch *ds, int port,
304344 struct flow_cls_offload *cls, bool ingress)
305345 {
@@ -321,12 +361,9 @@ int sja1105_cls_flower_add(struct dsa_switch *ds, int port, · 15 unmodified lines
321361 flow_action_for_each(i, act, &rule->action) {
322362 switch (act->id) {
323363 case FLOW_ACTION_POLICE:
324− if (act->police.rate_pkt_ps) {
325− NL_SET_ERR_MSG_MOD(extack,
326− "QoS offload not support packets per second");
327− rc = -EOPNOTSUPP;
364+ rc = sja1105_policer_validate(&rule->action, act, extack);
365+ if (rc)
328366 goto out;
329− }
330367
331368 rc = sja1105_flower_policer(priv, port, extack, cookie,
332369 &key,
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c+49−10
@@ -8,6 +8,46 @@ · 7 unmodified lines
88 #include "cxgb4_filter.h"
99 #include "cxgb4_tc_flower.h"
1010
11+static int cxgb4_policer_validate(const struct flow_action *action,
12+ const struct flow_action_entry *act,
13+ struct netlink_ext_ack *extack)
14+{
15+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
16+ NL_SET_ERR_MSG_MOD(extack,
17+ "Offload not supported when exceed action is not drop");
18+ return -EOPNOTSUPP;
19+ }
20+
21+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
22+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
23+ NL_SET_ERR_MSG_MOD(extack,
24+ "Offload not supported when conform action is not pipe or ok");
25+ return -EOPNOTSUPP;
26+ }
27+
28+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
29+ !flow_action_is_last_entry(action, act)) {
30+ NL_SET_ERR_MSG_MOD(extack,
31+ "Offload not supported when conform action is ok, but action is not last");
32+ return -EOPNOTSUPP;
33+ }
34+
35+ if (act->police.peakrate_bytes_ps ||
36+ act->police.avrate || act->police.overhead) {
37+ NL_SET_ERR_MSG_MOD(extack,
38+ "Offload not supported when peakrate/avrate/overhead is configured");
39+ return -EOPNOTSUPP;
40+ }
41+
42+ if (act->police.rate_pkt_ps) {
43+ NL_SET_ERR_MSG_MOD(extack,
44+ "QoS offload not support packets per second");
45+ return -EOPNOTSUPP;
46+ }
47+
48+ return 0;
49+}
50+
1151 static int cxgb4_matchall_egress_validate(struct net_device *dev,
1252 struct tc_cls_matchall_offload *cls)
1353 {
@@ -48,11 +88,10 @@ static int cxgb4_matchall_egress_validate(struct net_device *dev, · 34 unmodified lines
4888 flow_action_for_each(i, entry, actions) {
4989 switch (entry->id) {
5090 case FLOW_ACTION_POLICE:
51− if (entry->police.rate_pkt_ps) {
52− NL_SET_ERR_MSG_MOD(extack,
53− "QoS offload not support packets per second");
54− return -EOPNOTSUPP;
55− }
91+ ret = cxgb4_policer_validate(actions, entry, extack);
92+ if (ret)
93+ return ret;
94+
5695 /* Convert bytes per second to bits per second */
5796 if (entry->police.rate_bytes_ps * 8 > max_link_rate) {
5897 NL_SET_ERR_MSG_MOD(extack,
@@ -150,11 +189,11 @@ static int cxgb4_matchall_alloc_tc(struct net_device *dev, · 91 unmodified lines
150189 flow_action_for_each(i, entry, &cls->rule->action)
151190 if (entry->id == FLOW_ACTION_POLICE)
152191 break;
153− if (entry->police.rate_pkt_ps) {
154− NL_SET_ERR_MSG_MOD(extack,
155− "QoS offload not support packets per second");
156− return -EOPNOTSUPP;
157− }
192+
193+ ret = cxgb4_policer_validate(&cls->rule->action, entry, extack);
194+ if (ret)
195+ return ret;
196+
158197 /* Convert from bytes per second to Kbps */
159198 p.u.params.maxrate = div_u64(entry->police.rate_bytes_ps * 8, 1000);
160199 p.u.params.channel = pi->tx_chan;
drivers/net/ethernet/freescale/enetc/enetc_qos.c+43−4
@@ -1021,6 +1021,46 @@ static struct actions_fwd *enetc_check_flow_actions(u64 acts, · 1020 unmodified lines
10211021 return NULL;
10221022 }
10231023
1024+static int enetc_psfp_policer_validate(const struct flow_action *action,
1025+ const struct flow_action_entry *act,
1026+ struct netlink_ext_ack *extack)
1027+{
1028+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
1029+ NL_SET_ERR_MSG_MOD(extack,
1030+ "Offload not supported when exceed action is not drop");
1031+ return -EOPNOTSUPP;
1032+ }
1033+
1034+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
1035+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
1036+ NL_SET_ERR_MSG_MOD(extack,
1037+ "Offload not supported when conform action is not pipe or ok");
1038+ return -EOPNOTSUPP;
1039+ }
1040+
1041+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
1042+ !flow_action_is_last_entry(action, act)) {
1043+ NL_SET_ERR_MSG_MOD(extack,
1044+ "Offload not supported when conform action is ok, but action is not last");
1045+ return -EOPNOTSUPP;
1046+ }
1047+
1048+ if (act->police.peakrate_bytes_ps ||
1049+ act->police.avrate || act->police.overhead) {
1050+ NL_SET_ERR_MSG_MOD(extack,
1051+ "Offload not supported when peakrate/avrate/overhead is configured");
1052+ return -EOPNOTSUPP;
1053+ }
1054+
1055+ if (act->police.rate_pkt_ps) {
1056+ NL_SET_ERR_MSG_MOD(extack,
1057+ "QoS offload not support packets per second");
1058+ return -EOPNOTSUPP;
1059+ }
1060+
1061+ return 0;
1062+}
1063+
10241064 static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv,
10251065 struct flow_cls_offload *f)
10261066 {
@@ -1177,11 +1217,10 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, · 150 unmodified lines
11771217
11781218 /* Flow meter and max frame size */
11791219 if (entryp) {
1180− if (entryp->police.rate_pkt_ps) {
1181− NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");
1182− err = -EOPNOTSUPP;
1220+ err = enetc_psfp_policer_validate(&rule->action, entryp, extack);
1221+ if (err)
11831222 goto free_sfi;
1184− }
1223+
11851224 if (entryp->police.burst) {
11861225 fmi = kzalloc(sizeof(*fmi), GFP_KERNEL);
11871226 if (!fmi) {
drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c+43−0
@@ -190,6 +190,40 @@ static int otx2_tc_validate_flow(struct otx2_nic *nic, · 189 unmodified lines
190190 return 0;
191191 }
192192
193+static int otx2_policer_validate(const struct flow_action *action,
194+ const struct flow_action_entry *act,
195+ struct netlink_ext_ack *extack)
196+{
197+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
198+ NL_SET_ERR_MSG_MOD(extack,
199+ "Offload not supported when exceed action is not drop");
200+ return -EOPNOTSUPP;
201+ }
202+
203+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
204+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
205+ NL_SET_ERR_MSG_MOD(extack,
206+ "Offload not supported when conform action is not pipe or ok");
207+ return -EOPNOTSUPP;
208+ }
209+
210+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
211+ !flow_action_is_last_entry(action, act)) {
212+ NL_SET_ERR_MSG_MOD(extack,
213+ "Offload not supported when conform action is ok, but action is not last");
214+ return -EOPNOTSUPP;
215+ }
216+
217+ if (act->police.peakrate_bytes_ps ||
218+ act->police.avrate || act->police.overhead) {
219+ NL_SET_ERR_MSG_MOD(extack,
220+ "Offload not supported when peakrate/avrate/overhead is configured");
221+ return -EOPNOTSUPP;
222+ }
223+
224+ return 0;
225+}
226+
193227 static int otx2_tc_egress_matchall_install(struct otx2_nic *nic,
194228 struct tc_cls_matchall_offload *cls)
195229 {
@@ -212,6 +246,10 @@ static int otx2_tc_egress_matchall_install(struct otx2_nic *nic, · 16 unmodified lines
212246 entry = &cls->rule->action.entries[0];
213247 switch (entry->id) {
214248 case FLOW_ACTION_POLICE:
249+ err = otx2_policer_validate(&cls->rule->action, entry, extack);
250+ if (err)
251+ return err;
252+
215253 if (entry->police.rate_pkt_ps) {
216254 NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");
217255 return -EOPNOTSUPP;
@@ -315,6 +353,7 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic, · 97 unmodified lines
315353 u8 nr_police = 0;
316354 bool pps = false;
317355 u64 rate;
356+ int err;
318357 int i;
319358
320359 if (!flow_action_has_entries(flow_action)) {
@@ -355,6 +394,10 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic, · 34 unmodified lines
355394 return -EOPNOTSUPP;
356395 }
357396
397+ err = otx2_policer_validate(flow_action, act, extack);
398+ if (err)
399+ return err;
400+
358401 if (act->police.rate_bytes_ps > 0) {
359402 rate = act->police.rate_bytes_ps * 8;
360403 burst = act->police.burst;
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c+44−4
@@ -4482,6 +4482,46 @@ static int apply_police_params(struct mlx5e_priv *priv, u64 rate, · 4481 unmodified lines
44824482 return err;
44834483 }
44844484
4485+static int mlx5e_policer_validate(const struct flow_action *action,
4486+ const struct flow_action_entry *act,
4487+ struct netlink_ext_ack *extack)
4488+{
4489+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
4490+ NL_SET_ERR_MSG_MOD(extack,
4491+ "Offload not supported when exceed action is not drop");
4492+ return -EOPNOTSUPP;
4493+ }
4494+
4495+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
4496+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
4497+ NL_SET_ERR_MSG_MOD(extack,
4498+ "Offload not supported when conform action is not pipe or ok");
4499+ return -EOPNOTSUPP;
4500+ }
4501+
4502+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
4503+ !flow_action_is_last_entry(action, act)) {
4504+ NL_SET_ERR_MSG_MOD(extack,
4505+ "Offload not supported when conform action is ok, but action is not last");
4506+ return -EOPNOTSUPP;
4507+ }
4508+
4509+ if (act->police.peakrate_bytes_ps ||
4510+ act->police.avrate || act->police.overhead) {
4511+ NL_SET_ERR_MSG_MOD(extack,
4512+ "Offload not supported when peakrate/avrate/overhead is configured");
4513+ return -EOPNOTSUPP;
4514+ }
4515+
4516+ if (act->police.rate_pkt_ps) {
4517+ NL_SET_ERR_MSG_MOD(extack,
4518+ "QoS offload not support packets per second");
4519+ return -EOPNOTSUPP;
4520+ }
4521+
4522+ return 0;
4523+}
4524+
44854525 static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv,
44864526 struct flow_action *flow_action,
44874527 struct netlink_ext_ack *extack)
@@ -4509,10 +4549,10 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv, · 21 unmodified lines
45094549 flow_action_for_each(i, act, flow_action) {
45104550 switch (act->id) {
45114551 case FLOW_ACTION_POLICE:
4512− if (act->police.rate_pkt_ps) {
4513− NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");
4514− return -EOPNOTSUPP;
4515− }
4552+ err = mlx5e_policer_validate(flow_action, act, extack);
4553+ if (err)
4554+ return err;
4555+
45164556 err = apply_police_params(priv, act->police.rate_bytes_ps, extack);
45174557 if (err)
45184558 return err;
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c+43−4
@@ -15,6 +15,46 @@ · 14 unmodified lines
1515 #include "spectrum.h"
1616 #include "core_acl_flex_keys.h"
1717
18+static int mlxsw_sp_policer_validate(const struct flow_action *action,
19+ const struct flow_action_entry *act,
20+ struct netlink_ext_ack *extack)
21+{
22+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
23+ NL_SET_ERR_MSG_MOD(extack,
24+ "Offload not supported when exceed action is not drop");
25+ return -EOPNOTSUPP;
26+ }
27+
28+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
29+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
30+ NL_SET_ERR_MSG_MOD(extack,
31+ "Offload not supported when conform action is not pipe or ok");
32+ return -EOPNOTSUPP;
33+ }
34+
35+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
36+ !flow_action_is_last_entry(action, act)) {
37+ NL_SET_ERR_MSG_MOD(extack,
38+ "Offload not supported when conform action is ok, but action is not last");
39+ return -EOPNOTSUPP;
40+ }
41+
42+ if (act->police.peakrate_bytes_ps ||
43+ act->police.avrate || act->police.overhead) {
44+ NL_SET_ERR_MSG_MOD(extack,
45+ "Offload not supported when peakrate/avrate/overhead is configured");
46+ return -EOPNOTSUPP;
47+ }
48+
49+ if (act->police.rate_pkt_ps) {
50+ NL_SET_ERR_MSG_MOD(extack,
51+ "QoS offload not support packets per second");
52+ return -EOPNOTSUPP;
53+ }
54+
55+ return 0;
56+}
57+
1858 static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
1959 struct mlxsw_sp_flow_block *block,
2060 struct mlxsw_sp_acl_rule_info *rulei,
@@ -191,10 +231,9 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, · 170 unmodified lines
191231 return -EOPNOTSUPP;
192232 }
193233
194− if (act->police.rate_pkt_ps) {
195− NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second");
196− return -EOPNOTSUPP;
197− }
234+ err = mlxsw_sp_policer_validate(flow_action, act, extack);
235+ if (err)
236+ return err;
198237
199238 /* The kernel might adjust the requested burst size so
200239 * that it is not exactly a power of two. Re-adjust it
drivers/net/ethernet/mscc/ocelot_flower.c+8−6
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <net/pkt_cls.h>
77 #include <net/tc_act/tc_gact.h>
88 #include <soc/mscc/ocelot_vcap.h>
9+#include "ocelot_police.h"
910 #include "ocelot_vcap.h"
1011
1112 /* Arbitrarily chosen constants for encoding the VCAP block and lookup number
@@ -217,6 +218,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 205 unmodified lines
217218 bool ingress, struct flow_cls_offload *f,
218219 struct ocelot_vcap_filter *filter)
219220 {
221+ const struct flow_action *action = &f->rule->action;
220222 struct netlink_ext_ack *extack = f->common.extack;
221223 bool allow_missing_goto_target = false;
222224 const struct flow_action_entry *a;
@@ -244,7 +246,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 21 unmodified lines
244246 filter->goto_target = -1;
245247 filter->type = OCELOT_VCAP_FILTER_DUMMY;
246248
247− flow_action_for_each(i, a, &f->rule->action) {
249+ flow_action_for_each(i, a, action) {
248250 switch (a->id) {
249251 case FLOW_ACTION_DROP:
250252 if (filter->block_id != VCAP_IS2) {
@@ -297,11 +299,11 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 46 unmodified lines
297299 "Last action must be GOTO");
298300 return -EOPNOTSUPP;
299301 }
300− if (a->police.rate_pkt_ps) {
301− NL_SET_ERR_MSG_MOD(extack,
302− "QoS offload not support packets per second");
303− return -EOPNOTSUPP;
304− }
302+
303+ err = ocelot_policer_validate(action, a, extack);
304+ if (err)
305+ return err;
306+
305307 filter->action.police_ena = true;
306308
307309 pol_ix = a->hw_index + ocelot->vcap_pol.base;
drivers/net/ethernet/mscc/ocelot_net.c+5−5
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414 #include <linux/phy/phy.h>
1515 #include <net/pkt_cls.h>
1616 #include "ocelot.h"
17+#include "ocelot_police.h"
1718 #include "ocelot_vcap.h"
1819 #include "ocelot_fdma.h"
1920
@@ -258,11 +259,10 @@ static int ocelot_setup_tc_cls_matchall(struct ocelot_port_private *priv, · 238 unmodified lines
258259 return -EEXIST;
259260 }
260261
261− if (action->police.rate_pkt_ps) {
262− NL_SET_ERR_MSG_MOD(extack,
263− "QoS offload not support packets per second");
264− return -EOPNOTSUPP;
265− }
262+ err = ocelot_policer_validate(&f->rule->action, action,
263+ extack);
264+ if (err)
265+ return err;
266266
267267 pol.rate = (u32)div_u64(action->police.rate_bytes_ps, 1000) * 8;
268268 pol.burst = action->police.burst;
drivers/net/ethernet/mscc/ocelot_police.c+41−0
@@ -154,6 +154,47 @@ int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix, · 153 unmodified lines
154154 return 0;
155155 }
156156
157+int ocelot_policer_validate(const struct flow_action *action,
158+ const struct flow_action_entry *a,
159+ struct netlink_ext_ack *extack)
160+{
161+ if (a->police.exceed.act_id != FLOW_ACTION_DROP) {
162+ NL_SET_ERR_MSG_MOD(extack,
163+ "Offload not supported when exceed action is not drop");
164+ return -EOPNOTSUPP;
165+ }
166+
167+ if (a->police.notexceed.act_id != FLOW_ACTION_PIPE &&
168+ a->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
169+ NL_SET_ERR_MSG_MOD(extack,
170+ "Offload not supported when conform action is not pipe or ok");
171+ return -EOPNOTSUPP;
172+ }
173+
174+ if (a->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
175+ !flow_action_is_last_entry(action, a)) {
176+ NL_SET_ERR_MSG_MOD(extack,
177+ "Offload not supported when conform action is ok, but police action is not last");
178+ return -EOPNOTSUPP;
179+ }
180+
181+ if (a->police.peakrate_bytes_ps ||
182+ a->police.avrate || a->police.overhead) {
183+ NL_SET_ERR_MSG_MOD(extack,
184+ "Offload not supported when peakrate/avrate/overhead is configured");
185+ return -EOPNOTSUPP;
186+ }
187+
188+ if (a->police.rate_pkt_ps) {
189+ NL_SET_ERR_MSG_MOD(extack,
190+ "Offload does not support packets per second");
191+ return -EOPNOTSUPP;
192+ }
193+
194+ return 0;
195+}
196+EXPORT_SYMBOL(ocelot_policer_validate);
197+
157198 int ocelot_port_policer_add(struct ocelot *ocelot, int port,
158199 struct ocelot_policer *pol)
159200 {
drivers/net/ethernet/mscc/ocelot_police.h+5−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #define _MSCC_OCELOT_POLICE_H_
99
1010 #include "ocelot.h"
11+#include <net/flow_offload.h>
1112
1213 enum mscc_qos_rate_mode {
1314 MSCC_QOS_RATE_MODE_DISABLED, /* Policer/shaper disabled */
@@ -33,4 +34,8 @@ struct qos_policer_conf { · 19 unmodified lines
3334 int qos_policer_conf_set(struct ocelot *ocelot, int port, u32 pol_ix,
3435 struct qos_policer_conf *conf);
3536
37+int ocelot_policer_validate(const struct flow_action *action,
38+ const struct flow_action_entry *a,
39+ struct netlink_ext_ack *extack);
40+
3641 #endif /* _MSCC_OCELOT_POLICE_H_ */
drivers/net/ethernet/netronome/nfp/flower/qos_conf.c+40−0
@@ -117,6 +117,40 @@ int nfp_flower_offload_one_police(struct nfp_app *app, bool ingress, · 116 unmodified lines
117117 return 0;
118118 }
119119
120+static int nfp_policer_validate(const struct flow_action *action,
121+ const struct flow_action_entry *act,
122+ struct netlink_ext_ack *extack)
123+{
124+ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
125+ NL_SET_ERR_MSG_MOD(extack,
126+ "Offload not supported when exceed action is not drop");
127+ return -EOPNOTSUPP;
128+ }
129+
130+ if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
131+ act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
132+ NL_SET_ERR_MSG_MOD(extack,
133+ "Offload not supported when conform action is not pipe or ok");
134+ return -EOPNOTSUPP;
135+ }
136+
137+ if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
138+ !flow_action_is_last_entry(action, act)) {
139+ NL_SET_ERR_MSG_MOD(extack,
140+ "Offload not supported when conform action is ok, but action is not last");
141+ return -EOPNOTSUPP;
142+ }
143+
144+ if (act->police.peakrate_bytes_ps ||
145+ act->police.avrate || act->police.overhead) {
146+ NL_SET_ERR_MSG_MOD(extack,
147+ "Offload not supported when peakrate/avrate/overhead is configured");
148+ return -EOPNOTSUPP;
149+ }
150+
151+ return 0;
152+}
153+
120154 static int
121155 nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev,
122156 struct tc_cls_matchall_offload *flow,
@@ -135,6 +169,7 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev, · 12 unmodified lines
135169 u32 burst;
136170 bool pps;
137171 u64 rate;
172+ int err;
138173
139174 if (!nfp_netdev_is_nfp_repr(netdev)) {
140175 NL_SET_ERR_MSG_MOD(extack, "unsupported offload: qos rate limit offload not supported on higher level port");
@@ -181,6 +216,11 @@ nfp_flower_install_rate_limiter(struct nfp_app *app, struct net_device *netdev, · 40 unmodified lines
181216 "unsupported offload: qos rate limit offload requires police action");
182217 return -EOPNOTSUPP;
183218 }
219+
220+ err = nfp_policer_validate(&flow->rule->action, action, extack);
221+ if (err)
222+ return err;
223+
184224 if (action->police.rate_bytes_ps > 0) {
185225 if (bps_num++) {
186226 NL_SET_ERR_MSG_MOD(extack,
include/net/flow_offload.h+15−0
@@ -148,6 +148,8 @@ enum flow_action_id { · 147 unmodified lines
148148 FLOW_ACTION_MPLS_MANGLE,
149149 FLOW_ACTION_GATE,
150150 FLOW_ACTION_PPPOE_PUSH,
151+ FLOW_ACTION_JUMP,
152+ FLOW_ACTION_PIPE,
151153 NUM_FLOW_ACTIONS,
152154 };
153155
@@ -235,9 +237,16 @@ struct flow_action_entry { · 81 unmodified lines
235237 struct { /* FLOW_ACTION_POLICE */
236238 u32 burst;
237239 u64 rate_bytes_ps;
240+ u64 peakrate_bytes_ps;
241+ u32 avrate;
242+ u16 overhead;
238243 u64 burst_pkt;
239244 u64 rate_pkt_ps;
240245 u32 mtu;
246+ struct {
247+ enum flow_action_id act_id;
248+ u32 extval;
249+ } exceed, notexceed;
241250 } police;
242251 struct { /* FLOW_ACTION_CT */
243252 int action;
@@ -302,6 +311,12 @@ static inline bool flow_offload_has_one_action(const struct flow_action *action) · 58 unmodified lines
302311 return action->num_entries == 1;
303312 }
304313
314+static inline bool flow_action_is_last_entry(const struct flow_action *action,
315+ const struct flow_action_entry *entry)
316+{
317+ return entry == &action->entries[action->num_entries - 1];
318+}
319+
305320 #define flow_action_for_each(__i, __act, __actions) \
306321 for (__i = 0, __act = &(__actions)->entries[0]; \
307322 __i < (__actions)->num_entries; \
include/net/tc_act/tc_police.h+30−0
@@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act) · 158 unmodified lines
159159 return params->tcfp_mtu;
160160 }
161161
162+static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
163+{
164+ struct tcf_police *police = to_police(act);
165+ struct tcf_police_params *params;
166+
167+ params = rcu_dereference_protected(police->params,
168+ lockdep_is_held(&police->tcf_lock));
169+ return params->peak.rate_bytes_ps;
170+}
171+
172+static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
173+{
174+ struct tcf_police *police = to_police(act);
175+ struct tcf_police_params *params;
176+
177+ params = rcu_dereference_protected(police->params,
178+ lockdep_is_held(&police->tcf_lock));
179+ return params->tcfp_ewma_rate;
180+}
181+
182+static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
183+{
184+ struct tcf_police *police = to_police(act);
185+ struct tcf_police_params *params;
186+
187+ params = rcu_dereference_protected(police->params,
188+ lockdep_is_held(&police->tcf_lock));
189+ return params->rate.overhead;
190+}
191+
162192 #endif /* __NET_TC_POLICE_H */
net/sched/act_police.c+46−0
@@ -419,20 +419,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index) · 418 unmodified lines
419419 return tcf_idr_search(tn, a, index);
420420 }
421421
422+static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
423+{
424+ int act_id = -EOPNOTSUPP;
425+
426+ if (!TC_ACT_EXT_OPCODE(tc_act)) {
427+ if (tc_act == TC_ACT_OK)
428+ act_id = FLOW_ACTION_ACCEPT;
429+ else if (tc_act == TC_ACT_SHOT)
430+ act_id = FLOW_ACTION_DROP;
431+ else if (tc_act == TC_ACT_PIPE)
432+ act_id = FLOW_ACTION_PIPE;
433+ } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
434+ act_id = FLOW_ACTION_GOTO;
435+ *extval = tc_act & TC_ACT_EXT_VAL_MASK;
436+ } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
437+ act_id = FLOW_ACTION_JUMP;
438+ *extval = tc_act & TC_ACT_EXT_VAL_MASK;
439+ }
440+
441+ return act_id;
442+}
443+
422444 static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
423445 u32 *index_inc, bool bind)
424446 {
425447 if (bind) {
426448 struct flow_action_entry *entry = entry_data;
449+ struct tcf_police *police = to_police(act);
450+ struct tcf_police_params *p;
451+ int act_id;
452+
453+ p = rcu_dereference_protected(police->params,
454+ lockdep_is_held(&police->tcf_lock));
427455
428456 entry->id = FLOW_ACTION_POLICE;
429457 entry->police.burst = tcf_police_burst(act);
430458 entry->police.rate_bytes_ps =
431459 tcf_police_rate_bytes_ps(act);
460+ entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
461+ entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
462+ entry->police.overhead = tcf_police_rate_overhead(act);
432463 entry->police.burst_pkt = tcf_police_burst_pkt(act);
433464 entry->police.rate_pkt_ps =
434465 tcf_police_rate_pkt_ps(act);
435466 entry->police.mtu = tcf_police_tcfp_mtu(act);
467+
468+ act_id = tcf_police_act_to_flow_act(police->tcf_action,
469+ &entry->police.exceed.extval);
470+ if (act_id < 0)
471+ return act_id;
472+
473+ entry->police.exceed.act_id = act_id;
474+
475+ act_id = tcf_police_act_to_flow_act(p->tcfp_result,
476+ &entry->police.notexceed.extval);
477+ if (act_id < 0)
478+ return act_id;
479+
480+ entry->police.notexceed.act_id = act_id;
481+
436482 *index_inc = 1;
437483 } else {
438484 struct flow_offload_action *fl_action = entry_data;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t