net: sched: Support specifying a starting chain via tc skb ext
Set the starting chain from the tc skb ext chain value. Once we read the tc skb ext, delete it, so cloned/redirect packets won't inherit it. In order to lookup a chain by the chain index on the ingress block at ingress classification, provide a lookup function. Co-developed-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Signed-off-by: Paul Blakey <paulb@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
parent
4371929819
commit
af699626ee
|
@ -454,6 +454,20 @@ static struct tcf_chain *tcf_chain_lookup(struct tcf_block *block,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
||||||
|
static struct tcf_chain *tcf_chain_lookup_rcu(const struct tcf_block *block,
|
||||||
|
u32 chain_index)
|
||||||
|
{
|
||||||
|
struct tcf_chain *chain;
|
||||||
|
|
||||||
|
list_for_each_entry_rcu(chain, &block->chain_list, list) {
|
||||||
|
if (chain->index == chain_index)
|
||||||
|
return chain;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
|
static int tc_chain_notify(struct tcf_chain *chain, struct sk_buff *oskb,
|
||||||
u32 seq, u16 flags, int event, bool unicast);
|
u32 seq, u16 flags, int event, bool unicast);
|
||||||
|
|
||||||
|
@ -1562,13 +1576,13 @@ static int tcf_block_setup(struct tcf_block *block,
|
||||||
*/
|
*/
|
||||||
static inline int __tcf_classify(struct sk_buff *skb,
|
static inline int __tcf_classify(struct sk_buff *skb,
|
||||||
const struct tcf_proto *tp,
|
const struct tcf_proto *tp,
|
||||||
|
const struct tcf_proto *orig_tp,
|
||||||
struct tcf_result *res,
|
struct tcf_result *res,
|
||||||
bool compat_mode,
|
bool compat_mode,
|
||||||
u32 *last_executed_chain)
|
u32 *last_executed_chain)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
const int max_reclassify_loop = 4;
|
const int max_reclassify_loop = 4;
|
||||||
const struct tcf_proto *orig_tp = tp;
|
|
||||||
const struct tcf_proto *first_tp;
|
const struct tcf_proto *first_tp;
|
||||||
int limit = 0;
|
int limit = 0;
|
||||||
|
|
||||||
|
@ -1619,7 +1633,7 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
|
||||||
{
|
{
|
||||||
u32 last_executed_chain = 0;
|
u32 last_executed_chain = 0;
|
||||||
|
|
||||||
return __tcf_classify(skb, tp, res, compat_mode,
|
return __tcf_classify(skb, tp, tp, res, compat_mode,
|
||||||
&last_executed_chain);
|
&last_executed_chain);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(tcf_classify);
|
EXPORT_SYMBOL(tcf_classify);
|
||||||
|
@ -1632,14 +1646,31 @@ int tcf_classify_ingress(struct sk_buff *skb,
|
||||||
#if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
#if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
|
||||||
u32 last_executed_chain = 0;
|
u32 last_executed_chain = 0;
|
||||||
|
|
||||||
return __tcf_classify(skb, tp, res, compat_mode,
|
return __tcf_classify(skb, tp, tp, res, compat_mode,
|
||||||
&last_executed_chain);
|
&last_executed_chain);
|
||||||
#else
|
#else
|
||||||
u32 last_executed_chain = tp ? tp->chain->index : 0;
|
u32 last_executed_chain = tp ? tp->chain->index : 0;
|
||||||
|
const struct tcf_proto *orig_tp = tp;
|
||||||
struct tc_skb_ext *ext;
|
struct tc_skb_ext *ext;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = __tcf_classify(skb, tp, res, compat_mode, &last_executed_chain);
|
ext = skb_ext_find(skb, TC_SKB_EXT);
|
||||||
|
|
||||||
|
if (ext && ext->chain) {
|
||||||
|
struct tcf_chain *fchain;
|
||||||
|
|
||||||
|
fchain = tcf_chain_lookup_rcu(ingress_block, ext->chain);
|
||||||
|
if (!fchain)
|
||||||
|
return TC_ACT_SHOT;
|
||||||
|
|
||||||
|
/* Consume, so cloned/redirect skbs won't inherit ext */
|
||||||
|
skb_ext_del(skb, TC_SKB_EXT);
|
||||||
|
|
||||||
|
tp = rcu_dereference_bh(fchain->filter_chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = __tcf_classify(skb, tp, orig_tp, res, compat_mode,
|
||||||
|
&last_executed_chain);
|
||||||
|
|
||||||
/* If we missed on some chain */
|
/* If we missed on some chain */
|
||||||
if (ret == TC_ACT_UNSPEC && last_executed_chain) {
|
if (ret == TC_ACT_UNSPEC && last_executed_chain) {
|
||||||
|
|
Loading…
Reference in New Issue