Skip to content

Commit

Permalink
net: sched: Support specifying a starting chain via tc skb ext
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Blakey authored and Saeed Mahameed committed Feb 20, 2020
1 parent 4371929 commit af69962
Showing 1 changed file with 35 additions and 4 deletions.
39 changes: 35 additions & 4 deletions net/sched/cls_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,20 @@ static struct tcf_chain *tcf_chain_lookup(struct tcf_block *block,
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,
u32 seq, u16 flags, int event, bool unicast);

Expand Down Expand Up @@ -1562,13 +1576,13 @@ static int tcf_block_setup(struct tcf_block *block,
*/
static inline int __tcf_classify(struct sk_buff *skb,
const struct tcf_proto *tp,
const struct tcf_proto *orig_tp,
struct tcf_result *res,
bool compat_mode,
u32 *last_executed_chain)
{
#ifdef CONFIG_NET_CLS_ACT
const int max_reclassify_loop = 4;
const struct tcf_proto *orig_tp = tp;
const struct tcf_proto *first_tp;
int limit = 0;

Expand Down Expand Up @@ -1619,7 +1633,7 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
{
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);
}
EXPORT_SYMBOL(tcf_classify);
Expand All @@ -1632,14 +1646,31 @@ int tcf_classify_ingress(struct sk_buff *skb,
#if !IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
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);
#else
u32 last_executed_chain = tp ? tp->chain->index : 0;
const struct tcf_proto *orig_tp = tp;
struct tc_skb_ext *ext;
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 (ret == TC_ACT_UNSPEC && last_executed_chain) {
Expand Down

0 comments on commit af69962

Please sign in to comment.