From 8d1a77f974ca61d39afa5bf0aeab210525d31475 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Wed, 20 Dec 2017 12:35:19 -0500 Subject: [PATCH] net: sch: api: add extack support in tcf_block_get This patch adds extack support for the function tcf_block_get which is a common used function in the tc subsystem. Callers which are interested in the receiving error can assign extack to get a more detailed information why tcf_block_get failed. Cc: David Ahern Acked-by: Jamal Hadi Salim Signed-off-by: Alexander Aring Signed-off-by: David S. Miller --- include/net/pkt_cls.h | 6 ++++-- net/sched/cls_api.c | 13 +++++++++---- net/sched/sch_atm.c | 6 ++++-- net/sched/sch_cbq.c | 4 ++-- net/sched/sch_drr.c | 2 +- net/sched/sch_dsmark.c | 2 +- net/sched/sch_fq_codel.c | 2 +- net/sched/sch_hfsc.c | 4 ++-- net/sched/sch_htb.c | 4 ++-- net/sched/sch_ingress.c | 8 +++++--- net/sched/sch_multiq.c | 2 +- net/sched/sch_prio.c | 2 +- net/sched/sch_qfq.c | 2 +- net/sched/sch_sfb.c | 2 +- net/sched/sch_sfq.c | 2 +- 15 files changed, 36 insertions(+), 25 deletions(-) diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 0105445cab83..58bba9c769ea 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -39,9 +39,11 @@ struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index, bool create); void tcf_chain_put(struct tcf_chain *chain); int tcf_block_get(struct tcf_block **p_block, - struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q); + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct netlink_ext_ack *extack); int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, - struct tcf_block_ext_info *ei); + struct tcf_block_ext_info *ei, + struct netlink_ext_ack *extack); void tcf_block_put(struct tcf_block *block); void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, struct tcf_block_ext_info *ei); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 22b977d40e1d..4591b87eaab5 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -281,20 +281,24 @@ static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q, } int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, - struct tcf_block_ext_info *ei) + struct tcf_block_ext_info *ei, + struct netlink_ext_ack *extack) { struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL); struct tcf_chain *chain; int err; - if (!block) + if (!block) { + NL_SET_ERR_MSG(extack, "Memory allocation for block failed"); return -ENOMEM; + } INIT_LIST_HEAD(&block->chain_list); INIT_LIST_HEAD(&block->cb_list); /* Create chain 0 by default, it has to be always present. */ chain = tcf_chain_create(block, 0); if (!chain) { + NL_SET_ERR_MSG(extack, "Failed to create new tcf chain"); err = -ENOMEM; goto err_chain_create; } @@ -321,7 +325,8 @@ static void tcf_chain_head_change_dflt(struct tcf_proto *tp_head, void *priv) } int tcf_block_get(struct tcf_block **p_block, - struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q) + struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, + struct netlink_ext_ack *extack) { struct tcf_block_ext_info ei = { .chain_head_change = tcf_chain_head_change_dflt, @@ -329,7 +334,7 @@ int tcf_block_get(struct tcf_block **p_block, }; WARN_ON(!p_filter_chain); - return tcf_block_get_ext(p_block, q, &ei); + return tcf_block_get_ext(p_block, q, &ei, extack); } EXPORT_SYMBOL(tcf_block_get); diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 8972ab72cda5..493d5c25d83a 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -283,7 +283,8 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, goto err_out; } - error = tcf_block_get(&flow->block, &flow->filter_list, sch); + error = tcf_block_get(&flow->block, &flow->filter_list, sch, + extack); if (error) { kfree(flow); goto err_out; @@ -550,7 +551,8 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt, p->link.q = &noop_qdisc; pr_debug("atm_tc_init: link (%p) qdisc %p\n", &p->link, p->link.q); - err = tcf_block_get(&p->link.block, &p->link.filter_list, sch); + err = tcf_block_get(&p->link.block, &p->link.filter_list, sch, + extack); if (err) return err; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 79f081eb6bb0..248ea26997b9 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1160,7 +1160,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt, if (!q->link.R_tab) return -EINVAL; - err = tcf_block_get(&q->link.block, &q->link.filter_list, sch); + err = tcf_block_get(&q->link.block, &q->link.filter_list, sch, extack); if (err) goto put_rtab; @@ -1576,7 +1576,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t if (cl == NULL) goto failure; - err = tcf_block_get(&cl->block, &cl->filter_list, sch); + err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); if (err) { kfree(cl); return err; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 30e9cba54ddb..9dfff065e27d 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -417,7 +417,7 @@ static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt, struct drr_sched *q = qdisc_priv(sch); int err; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; err = qdisc_class_hash_init(&q->clhash); diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 92a36aa4c713..63f523b5e282 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -348,7 +348,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt, if (!opt) goto errout; - err = tcf_block_get(&p->block, &p->filter_list, sch); + err = tcf_block_get(&p->block, &p->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 06e5360c54d8..22fa13cf5d8b 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -484,7 +484,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, return err; } - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 7f6a06ac4b9f..9ae288fcbed8 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1034,7 +1034,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (cl == NULL) return -ENOBUFS; - err = tcf_block_get(&cl->block, &cl->filter_list, sch); + err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); if (err) { kfree(cl); return err; @@ -1409,7 +1409,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt, return err; q->eligible = RB_ROOT; - err = tcf_block_get(&q->root.block, &q->root.filter_list, sch); + err = tcf_block_get(&q->root.block, &q->root.filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 51be1b756e4e..54e1f860f1e5 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1032,7 +1032,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, if (!opt) return -EINVAL; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; @@ -1397,7 +1397,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, if (!cl) goto failure; - err = tcf_block_get(&cl->block, &cl->filter_list, sch); + err = tcf_block_get(&cl->block, &cl->filter_list, sch, extack); if (err) { kfree(cl); goto failure; diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index b9de7be531dd..7ca2be20dd6f 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c @@ -78,7 +78,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt, q->block_info.chain_head_change = clsact_chain_head_change; q->block_info.chain_head_change_priv = &q->miniqp; - err = tcf_block_get_ext(&q->block, sch, &q->block_info); + err = tcf_block_get_ext(&q->block, sch, &q->block_info, extack); if (err) return err; @@ -186,7 +186,8 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt, q->ingress_block_info.chain_head_change = clsact_chain_head_change; q->ingress_block_info.chain_head_change_priv = &q->miniqp_ingress; - err = tcf_block_get_ext(&q->ingress_block, sch, &q->ingress_block_info); + err = tcf_block_get_ext(&q->ingress_block, sch, &q->ingress_block_info, + extack); if (err) return err; @@ -196,7 +197,8 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt, q->egress_block_info.chain_head_change = clsact_chain_head_change; q->egress_block_info.chain_head_change_priv = &q->miniqp_egress; - err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); + err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info, + extack); if (err) return err; diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 177d86de4b32..35cbaf8bd96a 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -248,7 +248,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt, if (!opt) return -EINVAL; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 8fbd65661d77..502352762f03 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -215,7 +215,7 @@ static int prio_init(struct Qdisc *sch, struct nlattr *opt, if (!opt) return -EINVAL; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 7ec893f770d2..6ab58509cf49 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -1424,7 +1424,7 @@ static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt, int i, j, err; u32 max_cl_shift, maxbudg_shift, max_classes; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c index 1a33d6c3ac42..a1a11ded8e4f 100644 --- a/net/sched/sch_sfb.c +++ b/net/sched/sch_sfb.c @@ -556,7 +556,7 @@ static int sfb_init(struct Qdisc *sch, struct nlattr *opt, struct sfb_sched_data *q = qdisc_priv(sch); int err; - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err; diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 7a217be39f2a..2f2678197760 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -731,7 +731,7 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt, q->sch = sch; timer_setup(&q->perturb_timer, sfq_perturbation, TIMER_DEFERRABLE); - err = tcf_block_get(&q->block, &q->filter_list, sch); + err = tcf_block_get(&q->block, &q->filter_list, sch, extack); if (err) return err;