net: flow_offload: add tc police action parameters
authorJianbo Liu <jianbol@nvidia.com>
Thu, 24 Feb 2022 10:29:07 +0000 (10:29 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Feb 2022 11:11:35 +0000 (11:11 +0000)
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 <jianbol@nvidia.com>
Signed-off-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/flow_offload.h
include/net/tc_act/tc_police.h
net/sched/act_police.c

index 5b8c54eb7a6b8a6e35d7f14e41f49898b585b456..74f44d44abe36986d90fef28c65de2adcc422436 100644 (file)
@@ -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;
index 72649512dcdd26dc864f2a1f3d6194c3c7010eb3..283bde711a425ff35000a71f0837aab477f0b1a3 100644 (file)
@@ -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 */
index 899fe025df7761bd925fcd718b14c2018f6f517f..f4d91770526390f2fa2b46157573b4f5fb2a0f66 100644 (file)
@@ -419,20 +419,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;