This also changes tcf_chain_get() to return an error pointer instead of NULL, so that tcf_action_goto_chain_init() can differentiate memory allocation failure from lack of support.
Fixes: 5bc1701881e3 ("net: sched: introduce multichain support for filters") Signed-off-by: Sabrina Dubroca <s...@queasysnail.net> --- I'm not sure this EOPNOTSUPP is really necessary, ie if we can really reach the tcf_action_goto_chain_init() call when CONFIG_NET_CLS=n. If not, a simpler patch would add a tcf_chain_get() stub that just returns NULL, as we wouldn't have to care about returning an incorrect error code from tcf_action_goto_chain_init(). include/net/pkt_cls.h | 7 +++++++ net/sched/act_api.c | 10 +++++++--- net/sched/cls_api.c | 10 +++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 2c213a69c196..ad0d2899529f 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -27,6 +27,13 @@ int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, struct tcf_result *res, bool compat_mode); #else +static inline struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index) +{ + return ERR_PTR(-EOPNOTSUPP); +} +static inline void tcf_chain_put(struct tcf_chain *chain) +{ +} static inline int tcf_block_get(struct tcf_block **p_block, struct tcf_proto __rcu **p_filter_chain) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 0ecf2a858767..502e0bbf35a6 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -31,12 +31,16 @@ static int tcf_action_goto_chain_init(struct tc_action *a, struct tcf_proto *tp) { u32 chain_index = a->tcfa_action & TC_ACT_EXT_VAL_MASK; + struct tcf_chain *chain; if (!tp) return -EINVAL; - a->goto_chain = tcf_chain_get(tp->chain->block, chain_index); - if (!a->goto_chain) - return -ENOMEM; + + chain = tcf_chain_get(tp->chain->block, chain_index); + if (IS_ERR(chain)) + return PTR_ERR(chain); + + a->goto_chain = chain; return 0; } diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 4020b8d932a1..8c14af3b77ae 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -193,7 +193,7 @@ static struct tcf_chain *tcf_chain_create(struct tcf_block *block, chain = kzalloc(sizeof(*chain), GFP_KERNEL); if (!chain) - return NULL; + return ERR_PTR(-ENOMEM); list_add_tail(&chain->list, &block->chain_list); chain->block = block; chain->index = chain_index; @@ -256,8 +256,8 @@ int tcf_block_get(struct tcf_block **p_block, INIT_LIST_HEAD(&block->chain_list); /* Create chain 0 by default, it has to be always present. */ chain = tcf_chain_create(block, 0); - if (!chain) { - err = -ENOMEM; + if (IS_ERR(chain)) { + err = PTR_ERR(chain); goto err_chain_create; } tcf_chain_filter_chain_ptr_set(chain, p_filter_chain); @@ -503,8 +503,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, goto errout; } chain = tcf_chain_get(block, chain_index); - if (!chain) { - err = -ENOMEM; + if (IS_ERR(chain)) { + err = PTR_ERR(chain); goto errout; } -- 2.13.0