diff options
author | David S. Miller <davem@davemloft.net> | 2016-03-10 16:24:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-10 16:24:03 -0500 |
commit | e8ab563f4b2e51849a16d962c6235b81e429c0d7 (patch) | |
tree | 293c390acdab0f7911ff42d7aba44b83c1020c8a /include/net | |
parent | 10f79037b4ac32e8929d73f31f908cfa061e29aa (diff) | |
parent | 12185a9fafa9cf39b73588c92aa49300ff3bf191 (diff) |
Merge branch 'flower-offload'
Amir Vadai says:
====================
cls_flower hardware offload support
Please see changes from V2 at the bottom.
This patchset introduces cls_flower hardware offload support over ConnectX-4
driver, more hardware vendors are welcome to use it too.
This patchset is based on John's infrastructure for tc offloading [2] to add
hardware offload support to the flower filter. It also extends the support to
an additional tc action - skbedit mark operation.
NIC driver that was used is ConnectX-4. Feature is off by default and could be
turned on using ethtool.
Some commands to use this code:
export TC=../iproute2/tc/tc
export ETH=ens9
ethtool -K ens9 hw-tc-offload on
$TC qdisc add dev $ETH ingress
$TC filter add dev $ETH protocol ip prio 20 parent ffff: \
flower ip_proto 1 \
dst_mac 7c:fe:90:69:81:62 \
src_mac 7c:fe:90:69:81:56 \
dst_ip 11.11.11.11 \
src_ip 11.11.11.12 \
indev $ETH \
action drop
$TC filter add dev $ETH protocol ip prio 30 parent ffff: \
flower ip_proto 6 \
indev $ETH \
action skbedit mark 0x1234
$TC filter add dev $ETH protocol ip prio 10 parent ffff: \
handle 0x1234 fw action pass
The code was tested and applied on top of commit 3ebeac1 ("Merge branch
'cxgb4-next'")
Changes from V2:
- patch 1/10 ("net/flower: Introduce hardware offload support")
- Remove unused variable [Dave]
- Don't fail command when HW can't offload filter [John]
- patch 3/10 ("net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef")
- Mention in changelog that struct tc_action is now exposed out of the ifdef.
- patch 4/10 ("net/act_skbedit: Utility functions for mark action")
- Document clearly that is_tcf_skbedit_mark() is returning true if and only
if the only action is mark [Dave]
- patch 8/10 ("net/mlx5e: Introduce tc offload support")
- make mlx5e_tc_add_flow() static
Changes from V1:
- patch 3/10 ("net/sched: Macro instead of CONFIG_NET_CLS_ACT ifdef")
- fixed return value of tc_no_actions
Changes from V0:
- Use tc_no_actions and tc_for_each_action instead of ifdef CONFIG_NET_CLS_ACT
- Replace ENOTSUPP (and some EINVAL) with EOPNOTSUPP
- Name the flower command enum
- fl_hw_destroy_filter() to return void - nobody uses the return value
- mlx5e_tc_init() and mlx5e_tc_cleanup() to be called from the right places.
- When adding HW rule fails - fail the command
- Rules are added to be processed both by HW and SW unless SKIP_HW is given
- Adding patch 6/10 ("net/mlx5e: Relax ndo_setup_tc handle restriction")
Main changes from the RFC [1]:
- API
- Using ndo_setup_tc() instead of switchdev
- act_skbedit, act_gact
- Actions are not serialized to NIC driver, instead using access functions.
- cls_flower
- prevent double classification by software by not adding
successfuly offloaded filters to the hashtable
- Fixed some bugs in original RFC with rule delete
- mlx5
- Adding flow table to kernel namespace instead of a new namespace
- s/offload/tc/ in many places
- no need for a special kconfig since switchdev is not used
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/act_api.h | 21 | ||||
-rw-r--r-- | include/net/flow_dissector.h | 13 | ||||
-rw-r--r-- | include/net/pkt_cls.h | 14 | ||||
-rw-r--r-- | include/net/tc_act/tc_gact.h | 4 | ||||
-rw-r--r-- | include/net/tc_act/tc_skbedit.h | 16 |
5 files changed, 61 insertions, 7 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 342be6c5ab5c..2a19fe111c78 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -78,11 +78,6 @@ static inline void tcf_lastuse_update(struct tcf_t *tm) tm->lastuse = now; } -#ifdef CONFIG_NET_CLS_ACT - -#define ACT_P_CREATED 1 -#define ACT_P_DELETED 1 - struct tc_action { void *priv; const struct tc_action_ops *ops; @@ -92,6 +87,11 @@ struct tc_action { struct tcf_hashinfo *hinfo; }; +#ifdef CONFIG_NET_CLS_ACT + +#define ACT_P_CREATED 1 +#define ACT_P_DELETED 1 + struct tc_action_ops { struct list_head head; char kind[IFNAMSIZ]; @@ -171,5 +171,16 @@ int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int); int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int, int); int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int); + +#define tc_no_actions(_exts) \ + (list_empty(&(_exts)->actions)) + +#define tc_for_each_action(_a, _exts) \ + list_for_each_entry(a, &(_exts)->actions, list) +#else /* CONFIG_NET_CLS_ACT */ + +#define tc_no_actions(_exts) true +#define tc_for_each_action(_a, _exts) while (0) + #endif /* CONFIG_NET_CLS_ACT */ #endif diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 8c8548cf5888..d3d60dccd19f 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -184,4 +184,17 @@ static inline bool flow_keys_have_l4(struct flow_keys *keys) u32 flow_hash_from_keys(struct flow_keys *keys); +static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector, + enum flow_dissector_key_id key_id) +{ + return flow_dissector->used_keys & (1 << key_id); +} + +static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector, + enum flow_dissector_key_id key_id, + void *target_container) +{ + return ((char *)target_container) + flow_dissector->offset[key_id]; +} + #endif diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index bea14eee373e..5b4e8f08b8f0 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -409,4 +409,18 @@ static inline bool tc_should_offload(struct net_device *dev, u32 flags) return true; } +enum tc_fl_command { + TC_CLSFLOWER_REPLACE, + TC_CLSFLOWER_DESTROY, +}; + +struct tc_cls_flower_offload { + enum tc_fl_command command; + u64 cookie; + struct flow_dissector *dissector; + struct fl_flow_key *mask; + struct fl_flow_key *key; + struct tcf_exts *exts; +}; + #endif diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h index 04a31830711b..93c520b83d10 100644 --- a/include/net/tc_act/tc_gact.h +++ b/include/net/tc_act/tc_gact.h @@ -16,9 +16,9 @@ struct tcf_gact { #define to_gact(a) \ container_of(a->priv, struct tcf_gact, common) -#ifdef CONFIG_NET_CLS_ACT static inline bool is_tcf_gact_shot(const struct tc_action *a) { +#ifdef CONFIG_NET_CLS_ACT struct tcf_gact *gact; if (a->ops && a->ops->type != TCA_ACT_GACT) @@ -28,7 +28,7 @@ static inline bool is_tcf_gact_shot(const struct tc_action *a) if (gact->tcf_action == TC_ACT_SHOT) return true; +#endif return false; } -#endif #endif /* __NET_TC_GACT_H */ diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h index 0df9a0db4a8e..b496d5ad7d42 100644 --- a/include/net/tc_act/tc_skbedit.h +++ b/include/net/tc_act/tc_skbedit.h @@ -20,6 +20,7 @@ #define __NET_TC_SKBEDIT_H #include <net/act_api.h> +#include <linux/tc_act/tc_skbedit.h> struct tcf_skbedit { struct tcf_common common; @@ -32,4 +33,19 @@ struct tcf_skbedit { #define to_skbedit(a) \ container_of(a->priv, struct tcf_skbedit, common) +/* Return true iff action is mark */ +static inline bool is_tcf_skbedit_mark(const struct tc_action *a) +{ +#ifdef CONFIG_NET_CLS_ACT + if (a->ops && a->ops->type == TCA_ACT_SKBEDIT) + return to_skbedit(a)->flags == SKBEDIT_F_MARK; +#endif + return false; +} + +static inline u32 tcf_skbedit_mark(const struct tc_action *a) +{ + return to_skbedit(a)->mark; +} + #endif /* __NET_TC_SKBEDIT_H */ |