summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-05-06 07:49:24 +0300
committerDavid S. Miller <davem@davemloft.net>2019-05-06 07:49:24 +0300
commit7e6a95d31b191d81639b089b6ff7a7995bcb4ac3 (patch)
tree4219c7cb2a12e4dcb82f7269483a68380e87198c /include
parentc8f8207ca6311be99ac855691490cd8764a9e31d (diff)
parent5fb5c395e2c4658a57f894ae9ab72b3d4d71a882 (diff)
downloadlinux-7e6a95d31b191d81639b089b6ff7a7995bcb4ac3.tar.xz
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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/flow_offload.h23
-rw-r--r--include/net/pkt_cls.h36
-rw-r--r--include/net/tc_act/tc_police.h70
3 files changed, 104 insertions, 25 deletions
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index d035183c8d03..6200900434e1 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -118,6 +118,8 @@ enum flow_action_id {
FLOW_ACTION_MARK,
FLOW_ACTION_WAKE,
FLOW_ACTION_QUEUE,
+ FLOW_ACTION_SAMPLE,
+ FLOW_ACTION_POLICE,
};
/* This is mirroring enum pedit_header_type definition for easy mapping between
@@ -157,6 +159,16 @@ struct flow_action_entry {
u32 index;
u8 vf;
} queue;
+ struct { /* FLOW_ACTION_SAMPLE */
+ struct psample_group *psample_group;
+ u32 rate;
+ u32 trunc_size;
+ bool truncate;
+ } sample;
+ struct { /* FLOW_ACTION_POLICE */
+ s64 burst;
+ u64 rate_bytes_ps;
+ } police;
};
};
@@ -170,6 +182,17 @@ static inline bool flow_action_has_entries(const struct flow_action *action)
return action->num_entries;
}
+/**
+ * flow_action_has_one_action() - check if exactly one action is present
+ * @action: tc filter flow offload action
+ *
+ * Returns true if exactly one action is present.
+ */
+static inline bool flow_offload_has_one_action(const struct flow_action *action)
+{
+ return action->num_entries == 1;
+}
+
#define flow_action_for_each(__i, __act, __actions) \
for (__i = 0, __act = &(__actions)->entries[0]; __i < (__actions)->num_entries; __act = &(__actions)->entries[++__i])
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index d5e7a1af346f..eed98f8fcb5e 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -100,6 +100,11 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
struct tcf_result *res, bool compat_mode);
#else
+static inline bool tcf_block_shared(struct tcf_block *block)
+{
+ return false;
+}
+
static inline
int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
@@ -372,30 +377,6 @@ static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
}
/**
- * tcf_exts_has_one_action - check if exactly one action is present
- * @exts: tc filter extensions handle
- *
- * Returns true if exactly one action is present.
- */
-static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
-{
-#ifdef CONFIG_NET_CLS_ACT
- return exts->nr_actions == 1;
-#else
- return false;
-#endif
-}
-
-static inline struct tc_action *tcf_exts_first_action(struct tcf_exts *exts)
-{
-#ifdef CONFIG_NET_CLS_ACT
- return exts->actions[0];
-#else
- return NULL;
-#endif
-}
-
-/**
* tcf_exts_exec - execute tc filter extensions
* @skb: socket buffer
* @exts: tc filter extensions handle
@@ -648,6 +629,7 @@ struct tc_cls_common_offload {
u32 chain_index;
__be16 protocol;
u32 prio;
+ struct tcf_block *block;
struct netlink_ext_ack *extack;
};
@@ -749,11 +731,13 @@ static inline bool tc_in_hw(u32 flags)
static inline void
tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
const struct tcf_proto *tp, u32 flags,
+ struct tcf_block *block,
struct netlink_ext_ack *extack)
{
cls_common->chain_index = tp->chain->index;
cls_common->protocol = tp->protocol;
cls_common->prio = tp->prio;
+ cls_common->block = block;
if (tc_skip_sw(flags) || flags & TCA_CLS_FLAGS_VERBOSE)
cls_common->extack = extack;
}
@@ -784,12 +768,14 @@ tc_cls_flower_offload_flow_rule(struct tc_cls_flower_offload *tc_flow_cmd)
enum tc_matchall_command {
TC_CLSMATCHALL_REPLACE,
TC_CLSMATCHALL_DESTROY,
+ TC_CLSMATCHALL_STATS,
};
struct tc_cls_matchall_offload {
struct tc_cls_common_offload common;
enum tc_matchall_command command;
- struct tcf_exts *exts;
+ struct flow_rule *rule;
+ struct flow_stats stats;
unsigned long cookie;
};
diff --git a/include/net/tc_act/tc_police.h b/include/net/tc_act/tc_police.h
new file mode 100644
index 000000000000..8b9ef3664262
--- /dev/null
+++ b/include/net/tc_act/tc_police.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_TC_POLICE_H
+#define __NET_TC_POLICE_H
+
+#include <net/act_api.h>
+
+struct tcf_police_params {
+ int tcfp_result;
+ u32 tcfp_ewma_rate;
+ s64 tcfp_burst;
+ u32 tcfp_mtu;
+ s64 tcfp_mtu_ptoks;
+ struct psched_ratecfg rate;
+ bool rate_present;
+ struct psched_ratecfg peak;
+ bool peak_present;
+ struct rcu_head rcu;
+};
+
+struct tcf_police {
+ struct tc_action common;
+ struct tcf_police_params __rcu *params;
+
+ spinlock_t tcfp_lock ____cacheline_aligned_in_smp;
+ s64 tcfp_toks;
+ s64 tcfp_ptoks;
+ s64 tcfp_t_c;
+};
+
+#define to_police(pc) ((struct tcf_police *)pc)
+
+/* old policer structure from before tc actions */
+struct tc_police_compat {
+ u32 index;
+ int action;
+ u32 limit;
+ u32 burst;
+ u32 mtu;
+ struct tc_ratespec rate;
+ struct tc_ratespec peakrate;
+};
+
+static inline bool is_tcf_police(const struct tc_action *act)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ if (act->ops && act->ops->id == TCA_ID_POLICE)
+ return true;
+#endif
+ return false;
+}
+
+static inline u64 tcf_police_rate_bytes_ps(const struct tc_action *act)
+{
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *params;
+
+ params = rcu_dereference_bh(police->params);
+ return params->rate.rate_bytes_ps;
+}
+
+static inline s64 tcf_police_tcfp_burst(const struct tc_action *act)
+{
+ struct tcf_police *police = to_police(act);
+ struct tcf_police_params *params;
+
+ params = rcu_dereference_bh(police->params);
+ return params->tcfp_burst;
+}
+
+#endif /* __NET_TC_POLICE_H */