2022-02-24 11:18:49

by Jianbo Liu

[permalink] [raw]
Subject: [PATCH net-next v3 0/2] 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.

Jianbo Liu (2):
net: flow_offload: add tc police action parameters
flow_offload: reject offload for all drivers with invalid police
parameters

drivers/net/dsa/sja1105/sja1105_flower.c | 47 +++++++++++++--
.../chelsio/cxgb4/cxgb4_tc_matchall.c | 59 +++++++++++++++----
.../net/ethernet/freescale/enetc/enetc_qos.c | 47 +++++++++++++--
.../ethernet/marvell/octeontx2/nic/otx2_tc.c | 43 ++++++++++++++
.../net/ethernet/mellanox/mlx5/core/en_tc.c | 48 +++++++++++++--
.../ethernet/mellanox/mlxsw/spectrum_flower.c | 47 +++++++++++++--
drivers/net/ethernet/mscc/ocelot_flower.c | 14 +++--
drivers/net/ethernet/mscc/ocelot_net.c | 10 ++--
drivers/net/ethernet/mscc/ocelot_police.c | 41 +++++++++++++
drivers/net/ethernet/mscc/ocelot_police.h | 5 ++
.../ethernet/netronome/nfp/flower/qos_conf.c | 40 +++++++++++++
include/net/flow_offload.h | 15 +++++
include/net/tc_act/tc_police.h | 30 ++++++++++
net/sched/act_police.c | 46 +++++++++++++++
14 files changed, 454 insertions(+), 38 deletions(-)

--
2.26.2


2022-02-24 11:44:28

by Jianbo Liu

[permalink] [raw]
Subject: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

The current police offload action entry is missing exceed/notexceed
actions and parameters that can be configured by tc police action.
Add the missing parameters as a pre-step for offloading police actions
to hardware.

Signed-off-by: Jianbo Liu <[email protected]>
Signed-off-by: Roi Dayan <[email protected]>
Reviewed-by: Ido Schimmel <[email protected]>
---
include/net/flow_offload.h | 9 +++++++
include/net/tc_act/tc_police.h | 30 ++++++++++++++++++++++
net/sched/act_police.c | 46 ++++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+)

diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index 5b8c54eb7a6b..74f44d44abe3 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -148,6 +148,8 @@ enum flow_action_id {
FLOW_ACTION_MPLS_MANGLE,
FLOW_ACTION_GATE,
FLOW_ACTION_PPPOE_PUSH,
+ FLOW_ACTION_JUMP,
+ FLOW_ACTION_PIPE,
NUM_FLOW_ACTIONS,
};

@@ -235,9 +237,16 @@ struct flow_action_entry {
struct { /* FLOW_ACTION_POLICE */
u32 burst;
u64 rate_bytes_ps;
+ u64 peakrate_bytes_ps;
+ u32 avrate;
+ u16 overhead;
u64 burst_pkt;
u64 rate_pkt_ps;
u32 mtu;
+ struct {
+ enum flow_action_id act_id;
+ u32 extval;
+ } exceed, notexceed;
} police;
struct { /* FLOW_ACTION_CT */
int action;
diff --git a/include/net/tc_act/tc_police.h b/include/net/tc_act/tc_police.h
index 72649512dcdd..283bde711a42 100644
--- a/include/net/tc_act/tc_police.h
+++ b/include/net/tc_act/tc_police.h
@@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
return params->tcfp_mtu;
}

+static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
+{
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *params;
+
+ params = rcu_dereference_protected(police->params,
+ lockdep_is_held(&police->tcf_lock));
+ return params->peak.rate_bytes_ps;
+}
+
+static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
+{
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *params;
+
+ params = rcu_dereference_protected(police->params,
+ lockdep_is_held(&police->tcf_lock));
+ return params->tcfp_ewma_rate;
+}
+
+static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
+{
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *params;
+
+ params = rcu_dereference_protected(police->params,
+ lockdep_is_held(&police->tcf_lock));
+ return params->rate.overhead;
+}
+
#endif /* __NET_TC_POLICE_H */
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 0923aa2b8f8a..a2275eef6877 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -405,20 +405,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
return tcf_idr_search(tn, a, index);
}

+static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
+{
+ int act_id = -EOPNOTSUPP;
+
+ if (!TC_ACT_EXT_OPCODE(tc_act)) {
+ if (tc_act == TC_ACT_OK)
+ act_id = FLOW_ACTION_ACCEPT;
+ else if (tc_act == TC_ACT_SHOT)
+ act_id = FLOW_ACTION_DROP;
+ else if (tc_act == TC_ACT_PIPE)
+ act_id = FLOW_ACTION_PIPE;
+ } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
+ act_id = FLOW_ACTION_GOTO;
+ *extval = tc_act & TC_ACT_EXT_VAL_MASK;
+ } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
+ act_id = FLOW_ACTION_JUMP;
+ *extval = tc_act & TC_ACT_EXT_VAL_MASK;
+ }
+
+ return act_id;
+}
+
static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
u32 *index_inc, bool bind)
{
if (bind) {
struct flow_action_entry *entry = entry_data;
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *p;
+ int act_id;
+
+ p = rcu_dereference_protected(police->params,
+ lockdep_is_held(&police->tcf_lock));

entry->id = FLOW_ACTION_POLICE;
entry->police.burst = tcf_police_burst(act);
entry->police.rate_bytes_ps =
tcf_police_rate_bytes_ps(act);
+ entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
+ entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
+ entry->police.overhead = tcf_police_rate_overhead(act);
entry->police.burst_pkt = tcf_police_burst_pkt(act);
entry->police.rate_pkt_ps =
tcf_police_rate_pkt_ps(act);
entry->police.mtu = tcf_police_tcfp_mtu(act);
+
+ act_id = tcf_police_act_to_flow_act(police->tcf_action,
+ &entry->police.exceed.extval);
+ if (act_id < 0)
+ return act_id;
+
+ entry->police.exceed.act_id = act_id;
+
+ act_id = tcf_police_act_to_flow_act(p->tcfp_result,
+ &entry->police.notexceed.extval);
+ if (act_id < 0)
+ return act_id;
+
+ entry->police.notexceed.act_id = act_id;
+
*index_inc = 1;
} else {
struct flow_offload_action *fl_action = entry_data;
--
2.26.2

2022-02-28 14:43:24

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH net-next v3 0/2] flow_offload: add tc police parameters

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <[email protected]>:

On Thu, 24 Feb 2022 10:29:06 +0000 you wrote:
> 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.
>
> [...]

Here is the summary with links:
- [net-next,v3,1/2] net: flow_offload: add tc police action parameters
https://git.kernel.org/netdev/net-next/c/b8cd5831c61c
- [net-next,v3,2/2] flow_offload: reject offload for all drivers with invalid police parameters
(no matching commit)

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html


2022-03-17 05:59:32

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

Hello Jianbo,

On Thu, Feb 24, 2022 at 10:29:07AM +0000, Jianbo Liu wrote:
> The current police offload action entry is missing exceed/notexceed
> actions and parameters that can be configured by tc police action.
> Add the missing parameters as a pre-step for offloading police actions
> to hardware.
>
> Signed-off-by: Jianbo Liu <[email protected]>
> Signed-off-by: Roi Dayan <[email protected]>
> Reviewed-by: Ido Schimmel <[email protected]>
> ---
> include/net/flow_offload.h | 9 +++++++
> include/net/tc_act/tc_police.h | 30 ++++++++++++++++++++++
> net/sched/act_police.c | 46 ++++++++++++++++++++++++++++++++++
> 3 files changed, 85 insertions(+)
>
> diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
> index 5b8c54eb7a6b..74f44d44abe3 100644
> --- a/include/net/flow_offload.h
> +++ b/include/net/flow_offload.h
> @@ -148,6 +148,8 @@ enum flow_action_id {
> FLOW_ACTION_MPLS_MANGLE,
> FLOW_ACTION_GATE,
> FLOW_ACTION_PPPOE_PUSH,
> + FLOW_ACTION_JUMP,
> + FLOW_ACTION_PIPE,
> NUM_FLOW_ACTIONS,
> };
>
> @@ -235,9 +237,16 @@ struct flow_action_entry {
> struct { /* FLOW_ACTION_POLICE */
> u32 burst;
> u64 rate_bytes_ps;
> + u64 peakrate_bytes_ps;
> + u32 avrate;
> + u16 overhead;
> u64 burst_pkt;
> u64 rate_pkt_ps;
> u32 mtu;
> + struct {
> + enum flow_action_id act_id;
> + u32 extval;
> + } exceed, notexceed;
> } police;
> struct { /* FLOW_ACTION_CT */
> int action;
> diff --git a/include/net/tc_act/tc_police.h b/include/net/tc_act/tc_police.h
> index 72649512dcdd..283bde711a42 100644
> --- a/include/net/tc_act/tc_police.h
> +++ b/include/net/tc_act/tc_police.h
> @@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
> return params->tcfp_mtu;
> }
>
> +static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
> +{
> + struct tcf_police *police = to_police(act);
> + struct tcf_police_params *params;
> +
> + params = rcu_dereference_protected(police->params,
> + lockdep_is_held(&police->tcf_lock));
> + return params->peak.rate_bytes_ps;
> +}
> +
> +static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
> +{
> + struct tcf_police *police = to_police(act);
> + struct tcf_police_params *params;
> +
> + params = rcu_dereference_protected(police->params,
> + lockdep_is_held(&police->tcf_lock));
> + return params->tcfp_ewma_rate;
> +}
> +
> +static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
> +{
> + struct tcf_police *police = to_police(act);
> + struct tcf_police_params *params;
> +
> + params = rcu_dereference_protected(police->params,
> + lockdep_is_held(&police->tcf_lock));
> + return params->rate.overhead;
> +}
> +
> #endif /* __NET_TC_POLICE_H */
> diff --git a/net/sched/act_police.c b/net/sched/act_police.c
> index 0923aa2b8f8a..a2275eef6877 100644
> --- a/net/sched/act_police.c
> +++ b/net/sched/act_police.c
> @@ -405,20 +405,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
> return tcf_idr_search(tn, a, index);
> }
>
> +static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
> +{
> + int act_id = -EOPNOTSUPP;
> +
> + if (!TC_ACT_EXT_OPCODE(tc_act)) {
> + if (tc_act == TC_ACT_OK)
> + act_id = FLOW_ACTION_ACCEPT;
> + else if (tc_act == TC_ACT_SHOT)
> + act_id = FLOW_ACTION_DROP;
> + else if (tc_act == TC_ACT_PIPE)
> + act_id = FLOW_ACTION_PIPE;
> + } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
> + act_id = FLOW_ACTION_GOTO;
> + *extval = tc_act & TC_ACT_EXT_VAL_MASK;
> + } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
> + act_id = FLOW_ACTION_JUMP;
> + *extval = tc_act & TC_ACT_EXT_VAL_MASK;
> + }
> +
> + return act_id;
> +}
> +
> static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
> u32 *index_inc, bool bind)
> {
> if (bind) {
> struct flow_action_entry *entry = entry_data;
> + struct tcf_police *police = to_police(act);
> + struct tcf_police_params *p;
> + int act_id;
> +
> + p = rcu_dereference_protected(police->params,
> + lockdep_is_held(&police->tcf_lock));
>
> entry->id = FLOW_ACTION_POLICE;
> entry->police.burst = tcf_police_burst(act);
> entry->police.rate_bytes_ps =
> tcf_police_rate_bytes_ps(act);
> + entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
> + entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
> + entry->police.overhead = tcf_police_rate_overhead(act);
> entry->police.burst_pkt = tcf_police_burst_pkt(act);
> entry->police.rate_pkt_ps =
> tcf_police_rate_pkt_ps(act);
> entry->police.mtu = tcf_police_tcfp_mtu(act);
> +
> + act_id = tcf_police_act_to_flow_act(police->tcf_action,
> + &entry->police.exceed.extval);

I don't know why just now, but I observed an apparent regression here
with these commands:

root@debian:~# tc qdisc add dev swp3 clsact
root@debian:~# tc filter add dev swp3 ingress protocol ip flower skip_sw ip_proto icmp action police rate 100Mbit burst 10000
[ 45.767900] tcf_police_act_to_flow_act: 434: tc_act 1
[ 45.773100] tcf_police_offload_act_setup: 475, act_id -95
Error: cls_flower: Failed to setup flow action.
We have an error talking to the kernel, -1

The reason why I'm not sure is because I don't know if this should have
worked as intended or not. I am remarking just now in "man tc-police"
that the default conform-exceed action is "reclassify".

So if I specify "conform-exceed drop", things are as expected, but with
the default (implicitly "conform-exceed reclassify") things fail with
-EOPNOTSUPP because tcf_police_act_to_flow_act() doesn't handle a
police->tcf_action of TC_ACT_RECLASSIFY.

Should it?

> + if (act_id < 0)
> + return act_id;
> +
> + entry->police.exceed.act_id = act_id;
> +
> + act_id = tcf_police_act_to_flow_act(p->tcfp_result,
> + &entry->police.notexceed.extval);
> + if (act_id < 0)
> + return act_id;
> +
> + entry->police.notexceed.act_id = act_id;
> +
> *index_inc = 1;
> } else {
> struct flow_offload_action *fl_action = entry_data;
> --
> 2.26.2
>

2022-03-17 20:16:19

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

On Thu, Mar 17, 2022 at 03:22:42PM +0200, Ido Schimmel wrote:
> > I don't know why just now, but I observed an apparent regression here
> > with these commands:
> >
> > root@debian:~# tc qdisc add dev swp3 clsact
> > root@debian:~# tc filter add dev swp3 ingress protocol ip flower skip_sw ip_proto icmp action police rate 100Mbit burst 10000
> > [ 45.767900] tcf_police_act_to_flow_act: 434: tc_act 1
> > [ 45.773100] tcf_police_offload_act_setup: 475, act_id -95
> > Error: cls_flower: Failed to setup flow action.
> > We have an error talking to the kernel, -1
> >
> > The reason why I'm not sure is because I don't know if this should have
> > worked as intended or not. I am remarking just now in "man tc-police"
> > that the default conform-exceed action is "reclassify".
> >
> > So if I specify "conform-exceed drop", things are as expected, but with
> > the default (implicitly "conform-exceed reclassify") things fail with
> > -EOPNOTSUPP because tcf_police_act_to_flow_act() doesn't handle a
> > police->tcf_action of TC_ACT_RECLASSIFY.
> >
> > Should it?
>
> Even if tcf_police_act_to_flow_act() handled "reclassify", the
> configuration would have been rejected later on by the relevant device
> driver since they all support "drop" for exceed action and nothing else.

This is correct, but currently, the error is:

Error: cls_flower: Failed to setup flow action.
We have an error talking to the kernel, -1

I'd appreciate if the error was instead:

Error: mscc_ocelot: Offload not supported when exceed action is not drop.

which is basically what Jianbo was trying to achieve when he added the
policer_validate() functions. At least I'd know what's wrong. No?

> I don't know why iproute2 defaults to "reclassify", but the
> configuration in the example does something different in the SW and HW
> data paths. One ugly suggestion to keep this case working it to have
> tcf_police_act_to_flow_act() default to "drop" and emit a warning via
> extack so that user space is at least aware of this misconfiguration.

I don't want to force a reinterpretation of "reclassify" just to make
something that used to work by mistake continue to work. It sucks to
have to adapt, but not being able to make progress because of such
things sucks even more.

I'd just like the 'reclassify' action to be propagated in some reasonable
way to flow offload, considering that at the moment the error is quite cryptic.

> > > + if (act_id < 0)
> > > + return act_id;
> > > +
> > > + entry->police.exceed.act_id = act_id;
> > > +
> > > + act_id = tcf_police_act_to_flow_act(p->tcfp_result,
> > > + &entry->police.notexceed.extval);
> > > + if (act_id < 0)
> > > + return act_id;
> > > +
> > > + entry->police.notexceed.act_id = act_id;
> > > +
> > > *index_inc = 1;
> > > } else {
> > > struct flow_offload_action *fl_action = entry_data;
> > > --
> > > 2.26.2
> > >

2022-03-17 20:42:06

by Ido Schimmel

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

On Tue, Mar 15, 2022 at 09:13:58PM +0200, Vladimir Oltean wrote:
> Hello Jianbo,
>
> On Thu, Feb 24, 2022 at 10:29:07AM +0000, Jianbo Liu wrote:
> > The current police offload action entry is missing exceed/notexceed
> > actions and parameters that can be configured by tc police action.
> > Add the missing parameters as a pre-step for offloading police actions
> > to hardware.
> >
> > Signed-off-by: Jianbo Liu <[email protected]>
> > Signed-off-by: Roi Dayan <[email protected]>
> > Reviewed-by: Ido Schimmel <[email protected]>
> > ---
> > include/net/flow_offload.h | 9 +++++++
> > include/net/tc_act/tc_police.h | 30 ++++++++++++++++++++++
> > net/sched/act_police.c | 46 ++++++++++++++++++++++++++++++++++
> > 3 files changed, 85 insertions(+)
> >
> > diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
> > index 5b8c54eb7a6b..74f44d44abe3 100644
> > --- a/include/net/flow_offload.h
> > +++ b/include/net/flow_offload.h
> > @@ -148,6 +148,8 @@ enum flow_action_id {
> > FLOW_ACTION_MPLS_MANGLE,
> > FLOW_ACTION_GATE,
> > FLOW_ACTION_PPPOE_PUSH,
> > + FLOW_ACTION_JUMP,
> > + FLOW_ACTION_PIPE,
> > NUM_FLOW_ACTIONS,
> > };
> >
> > @@ -235,9 +237,16 @@ struct flow_action_entry {
> > struct { /* FLOW_ACTION_POLICE */
> > u32 burst;
> > u64 rate_bytes_ps;
> > + u64 peakrate_bytes_ps;
> > + u32 avrate;
> > + u16 overhead;
> > u64 burst_pkt;
> > u64 rate_pkt_ps;
> > u32 mtu;
> > + struct {
> > + enum flow_action_id act_id;
> > + u32 extval;
> > + } exceed, notexceed;
> > } police;
> > struct { /* FLOW_ACTION_CT */
> > int action;
> > diff --git a/include/net/tc_act/tc_police.h b/include/net/tc_act/tc_police.h
> > index 72649512dcdd..283bde711a42 100644
> > --- a/include/net/tc_act/tc_police.h
> > +++ b/include/net/tc_act/tc_police.h
> > @@ -159,4 +159,34 @@ static inline u32 tcf_police_tcfp_mtu(const struct tc_action *act)
> > return params->tcfp_mtu;
> > }
> >
> > +static inline u64 tcf_police_peakrate_bytes_ps(const struct tc_action *act)
> > +{
> > + struct tcf_police *police = to_police(act);
> > + struct tcf_police_params *params;
> > +
> > + params = rcu_dereference_protected(police->params,
> > + lockdep_is_held(&police->tcf_lock));
> > + return params->peak.rate_bytes_ps;
> > +}
> > +
> > +static inline u32 tcf_police_tcfp_ewma_rate(const struct tc_action *act)
> > +{
> > + struct tcf_police *police = to_police(act);
> > + struct tcf_police_params *params;
> > +
> > + params = rcu_dereference_protected(police->params,
> > + lockdep_is_held(&police->tcf_lock));
> > + return params->tcfp_ewma_rate;
> > +}
> > +
> > +static inline u16 tcf_police_rate_overhead(const struct tc_action *act)
> > +{
> > + struct tcf_police *police = to_police(act);
> > + struct tcf_police_params *params;
> > +
> > + params = rcu_dereference_protected(police->params,
> > + lockdep_is_held(&police->tcf_lock));
> > + return params->rate.overhead;
> > +}
> > +
> > #endif /* __NET_TC_POLICE_H */
> > diff --git a/net/sched/act_police.c b/net/sched/act_police.c
> > index 0923aa2b8f8a..a2275eef6877 100644
> > --- a/net/sched/act_police.c
> > +++ b/net/sched/act_police.c
> > @@ -405,20 +405,66 @@ static int tcf_police_search(struct net *net, struct tc_action **a, u32 index)
> > return tcf_idr_search(tn, a, index);
> > }
> >
> > +static int tcf_police_act_to_flow_act(int tc_act, u32 *extval)
> > +{
> > + int act_id = -EOPNOTSUPP;
> > +
> > + if (!TC_ACT_EXT_OPCODE(tc_act)) {
> > + if (tc_act == TC_ACT_OK)
> > + act_id = FLOW_ACTION_ACCEPT;
> > + else if (tc_act == TC_ACT_SHOT)
> > + act_id = FLOW_ACTION_DROP;
> > + else if (tc_act == TC_ACT_PIPE)
> > + act_id = FLOW_ACTION_PIPE;
> > + } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_GOTO_CHAIN)) {
> > + act_id = FLOW_ACTION_GOTO;
> > + *extval = tc_act & TC_ACT_EXT_VAL_MASK;
> > + } else if (TC_ACT_EXT_CMP(tc_act, TC_ACT_JUMP)) {
> > + act_id = FLOW_ACTION_JUMP;
> > + *extval = tc_act & TC_ACT_EXT_VAL_MASK;
> > + }
> > +
> > + return act_id;
> > +}
> > +
> > static int tcf_police_offload_act_setup(struct tc_action *act, void *entry_data,
> > u32 *index_inc, bool bind)
> > {
> > if (bind) {
> > struct flow_action_entry *entry = entry_data;
> > + struct tcf_police *police = to_police(act);
> > + struct tcf_police_params *p;
> > + int act_id;
> > +
> > + p = rcu_dereference_protected(police->params,
> > + lockdep_is_held(&police->tcf_lock));
> >
> > entry->id = FLOW_ACTION_POLICE;
> > entry->police.burst = tcf_police_burst(act);
> > entry->police.rate_bytes_ps =
> > tcf_police_rate_bytes_ps(act);
> > + entry->police.peakrate_bytes_ps = tcf_police_peakrate_bytes_ps(act);
> > + entry->police.avrate = tcf_police_tcfp_ewma_rate(act);
> > + entry->police.overhead = tcf_police_rate_overhead(act);
> > entry->police.burst_pkt = tcf_police_burst_pkt(act);
> > entry->police.rate_pkt_ps =
> > tcf_police_rate_pkt_ps(act);
> > entry->police.mtu = tcf_police_tcfp_mtu(act);
> > +
> > + act_id = tcf_police_act_to_flow_act(police->tcf_action,
> > + &entry->police.exceed.extval);
>
> I don't know why just now, but I observed an apparent regression here
> with these commands:
>
> root@debian:~# tc qdisc add dev swp3 clsact
> root@debian:~# tc filter add dev swp3 ingress protocol ip flower skip_sw ip_proto icmp action police rate 100Mbit burst 10000
> [ 45.767900] tcf_police_act_to_flow_act: 434: tc_act 1
> [ 45.773100] tcf_police_offload_act_setup: 475, act_id -95
> Error: cls_flower: Failed to setup flow action.
> We have an error talking to the kernel, -1
>
> The reason why I'm not sure is because I don't know if this should have
> worked as intended or not. I am remarking just now in "man tc-police"
> that the default conform-exceed action is "reclassify".
>
> So if I specify "conform-exceed drop", things are as expected, but with
> the default (implicitly "conform-exceed reclassify") things fail with
> -EOPNOTSUPP because tcf_police_act_to_flow_act() doesn't handle a
> police->tcf_action of TC_ACT_RECLASSIFY.
>
> Should it?

Even if tcf_police_act_to_flow_act() handled "reclassify", the
configuration would have been rejected later on by the relevant device
driver since they all support "drop" for exceed action and nothing else.

I don't know why iproute2 defaults to "reclassify", but the
configuration in the example does something different in the SW and HW
data paths. One ugly suggestion to keep this case working it to have
tcf_police_act_to_flow_act() default to "drop" and emit a warning via
extack so that user space is at least aware of this misconfiguration.

>
> > + if (act_id < 0)
> > + return act_id;
> > +
> > + entry->police.exceed.act_id = act_id;
> > +
> > + act_id = tcf_police_act_to_flow_act(p->tcfp_result,
> > + &entry->police.notexceed.extval);
> > + if (act_id < 0)
> > + return act_id;
> > +
> > + entry->police.notexceed.act_id = act_id;
> > +
> > *index_inc = 1;
> > } else {
> > struct flow_offload_action *fl_action = entry_data;
> > --
> > 2.26.2
> >

2022-03-17 20:48:53

by Ido Schimmel

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

On Thu, Mar 17, 2022 at 08:52:49PM +0200, Vladimir Oltean wrote:
> I'd just like the 'reclassify' action to be propagated in some reasonable
> way to flow offload, considering that at the moment the error is quite cryptic.

OK, will check next week. Might be best to simply propagate extack to
offload_act_setup() and return a meaningful message in
tcf_police_offload_act_setup(). There are a bunch of other actions whose
callback simply returns '-EOPNOTSUPP' that can benefit from it.

2022-03-22 12:37:22

by Ido Schimmel

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

On Thu, Mar 17, 2022 at 09:37:22PM +0200, Ido Schimmel wrote:
> On Thu, Mar 17, 2022 at 08:52:49PM +0200, Vladimir Oltean wrote:
> > I'd just like the 'reclassify' action to be propagated in some reasonable
> > way to flow offload, considering that at the moment the error is quite cryptic.
>
> OK, will check next week. Might be best to simply propagate extack to
> offload_act_setup() and return a meaningful message in
> tcf_police_offload_act_setup(). There are a bunch of other actions whose
> callback simply returns '-EOPNOTSUPP' that can benefit from it.

# tc filter add dev dummy0 ingress protocol ip flower skip_sw ip_proto icmp action police rate 100Mbit burst 10000
Error: act_police: Offload not supported when conform/exceed action is "reclassify".
We have an error talking to the kernel

Available here:
https://github.com/idosch/linux/commits/tc_extack

I plan to submit the patches after net-next reopens.

2022-04-06 17:08:02

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/2] net: flow_offload: add tc police action parameters

On Tue, Mar 22, 2022 at 12:13:31PM +0200, Ido Schimmel wrote:
> On Thu, Mar 17, 2022 at 09:37:22PM +0200, Ido Schimmel wrote:
> > On Thu, Mar 17, 2022 at 08:52:49PM +0200, Vladimir Oltean wrote:
> > > I'd just like the 'reclassify' action to be propagated in some reasonable
> > > way to flow offload, considering that at the moment the error is quite cryptic.
> >
> > OK, will check next week. Might be best to simply propagate extack to
> > offload_act_setup() and return a meaningful message in
> > tcf_police_offload_act_setup(). There are a bunch of other actions whose
> > callback simply returns '-EOPNOTSUPP' that can benefit from it.
>
> # tc filter add dev dummy0 ingress protocol ip flower skip_sw ip_proto icmp action police rate 100Mbit burst 10000
> Error: act_police: Offload not supported when conform/exceed action is "reclassify".
> We have an error talking to the kernel
>
> Available here:
> https://github.com/idosch/linux/commits/tc_extack
>
> I plan to submit the patches after net-next reopens.

Thanks. I've tested these partially and at least the case that I
reported is now covered.