All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support
@ 2017-12-14 18:38 Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 01/15] net: sched: fix coding style issues Alexander Aring
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

Hi,

this patch series basically add support for extack in common qdisc handling.
Additional it adds extack pointer to common qdisc callback handling this
offers per qdisc implementation to setting the extack message for each
failure over netlink.

The extack message will be set deeper in qdisc functions but going not
deeper as net core api. For qdisc module callback handling, the extack
will not be set. This will be part of per qdisc extack handling.

I also want to prepare patches to handle extack per qdisc module...
so there will come a lot of more patches, just cut them down to make
it reviewable.

There are some above 80-chars width warnings, which I ignore because
it looks more ugly otherwise.

This patch-series based on patches by David Ahren which gave me some
hints how to deal with extack support.

Cc: David Ahern <dsahern@gmail.com>

changes since v2:
 - add fix coding style patch to catch all checkpatch warnings
 - add patch for setting netlink extack msg if validate_nla fails
 - changes in handle generic qdisc errors
   - remove NL_SET_ERR_MSG from memory allocation errors
   - remove NL_SET_ERR_MSG from device not found
   - change STAB to table size
 - add various new patches to add extack support for common
   TC functions like qdisc_get_rtab, tcf_block_get, qdisc_alloc
   and qdisc_create_dflt - users which are interessted in the
   detailed error messages can assign extack, otherwise NULL.
 - Add sch_cbq as example for qdisc_ops callback: init,
   qdisc_class_ops callbacks: change and graft
 - Add sch_cbs as example for qdisc_ops callback: change
 - Add sch_drr as example for qdisc_class ops callbacks: tcf_block

- Alex

Alexander Aring (15):
  net: sched: fix coding style issues
  lib: nlattr: set extack msg if validate_nla fails
  net: sched: sch_api: handle generic qdisc errors
  net: sched: sch: add extack for init callback
  net: sched: sch: add extack for change qdisc ops
  net: sched: sch: add extack to change class
  net: sched: sch: add extack for block callback
  net: sched: sch: add extack for graft callback
  net: sch: api: add extack support in qdisc_get_rtab
  net: sch: api: add extack support in tcf_block_get
  net: sch: api: add extack support in qdisc_alloc
  net: sch: api: add extack support in qdisc_create_dflt
  net: sch: sch_cbq: add extack support
  net: sch: sch_cbs: add extack support
  net: sch: sch_drr: add extack support

 include/net/pkt_cls.h     |   6 +-
 include/net/pkt_sched.h   |   6 +-
 include/net/sch_generic.h |  21 ++++--
 lib/nlattr.c              |   4 +-
 net/sched/act_police.c    |   4 +-
 net/sched/cls_api.c       |  17 +++--
 net/sched/sch_api.c       | 180 ++++++++++++++++++++++++++++++++--------------
 net/sched/sch_atm.c       |   3 +-
 net/sched/sch_cbq.c       |  78 +++++++++++++-------
 net/sched/sch_cbs.c       |  31 +++++---
 net/sched/sch_choke.c     |   8 ++-
 net/sched/sch_codel.c     |   8 ++-
 net/sched/sch_drr.c       |  40 +++++++----
 net/sched/sch_dsmark.c    |  19 +++--
 net/sched/sch_fifo.c      |  11 +--
 net/sched/sch_fq.c        |   8 ++-
 net/sched/sch_fq_codel.c  |  13 ++--
 net/sched/sch_generic.c   |  25 ++++---
 net/sched/sch_gred.c      |  13 ++--
 net/sched/sch_hfsc.c      |  28 ++++----
 net/sched/sch_hhf.c       |   8 ++-
 net/sched/sch_htb.c       |  29 ++++----
 net/sched/sch_ingress.c   |  20 ++++--
 net/sched/sch_mq.c        |   8 ++-
 net/sched/sch_mqprio.c    |   7 +-
 net/sched/sch_multiq.c    |  19 ++---
 net/sched/sch_netem.c     |  10 +--
 net/sched/sch_pie.c       |   8 ++-
 net/sched/sch_plug.c      |   6 +-
 net/sched/sch_prio.c      |  18 +++--
 net/sched/sch_qfq.c       |  22 +++---
 net/sched/sch_red.c       |  13 ++--
 net/sched/sch_sfb.c       |  20 +++---
 net/sched/sch_sfq.c       |   8 ++-
 net/sched/sch_tbf.c       |  21 +++---
 net/sched/sch_teql.c      |   3 +-
 36 files changed, 482 insertions(+), 261 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 01/15] net: sched: fix coding style issues
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails Alexander Aring
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs; +Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring

This patch fix checkpatch issues for upcomming patches according to the
sched api file. It changes mostly how to check on null pointer.

Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 net/sched/sch_api.c    |  2 +-
 net/sched/sch_cbq.c    | 12 ++++++------
 net/sched/sch_gred.c   |  7 ++++---
 net/sched/sch_hfsc.c   |  2 +-
 net/sched/sch_multiq.c |  2 +-
 net/sched/sch_tbf.c    |  2 +-
 6 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index a904276b657d..b54917f4ad87 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -669,7 +669,7 @@ int qdisc_class_hash_init(struct Qdisc_class_hash *clhash)
 	unsigned int size = 4;
 
 	clhash->hash = qdisc_class_hash_alloc(size);
-	if (clhash->hash == NULL)
+	if (!clhash->hash)
 		return -ENOMEM;
 	clhash->hashsize  = size;
 	clhash->hashmask  = size - 1;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 525eb3a6d625..0692fe35f4ec 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1150,12 +1150,13 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
 	if (err < 0)
 		return err;
 
-	if (tb[TCA_CBQ_RTAB] == NULL || tb[TCA_CBQ_RATE] == NULL)
+	if (!tb[TCA_CBQ_RTAB] || !tb[TCA_CBQ_RATE])
 		return -EINVAL;
 
 	r = nla_data(tb[TCA_CBQ_RATE]);
 
-	if ((q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB])) == NULL)
+	q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB]);
+	if (!q->link.R_tab)
 		return -EINVAL;
 
 	err = tcf_block_get(&q->link.block, &q->link.filter_list, sch);
@@ -1460,7 +1461,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	struct cbq_class *parent;
 	struct qdisc_rate_table *rtab = NULL;
 
-	if (opt == NULL)
+	if (!opt)
 		return -EINVAL;
 
 	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, NULL);
@@ -1532,8 +1533,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (parentid == TC_H_ROOT)
 		return -EINVAL;
 
-	if (tb[TCA_CBQ_WRROPT] == NULL || tb[TCA_CBQ_RATE] == NULL ||
-	    tb[TCA_CBQ_LSSOPT] == NULL)
+	if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT])
 		return -EINVAL;
 
 	rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
@@ -1565,7 +1565,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (parentid) {
 		parent = cbq_class_lookup(q, parentid);
 		err = -EINVAL;
-		if (parent == NULL)
+		if (!parent)
 			goto failure;
 	}
 
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index bc30f9186ac6..ccd1a00e2a9a 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -306,12 +306,13 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps)
 	struct tc_gred_sopt *sopt;
 	int i;
 
-	if (dps == NULL)
+	if (!dps)
 		return -EINVAL;
 
 	sopt = nla_data(dps);
 
-	if (sopt->DPs > MAX_DPs || sopt->DPs == 0 || sopt->def_DP >= sopt->DPs)
+	if (sopt->DPs > MAX_DPs || sopt->DPs == 0 ||
+	    sopt->def_DP >= sopt->DPs)
 		return -EINVAL;
 
 	sch_tree_lock(sch);
@@ -470,7 +471,7 @@ static int gred_init(struct Qdisc *sch, struct nlattr *opt)
 	struct nlattr *tb[TCA_GRED_MAX + 1];
 	int err;
 
-	if (opt == NULL)
+	if (!opt)
 		return -EINVAL;
 
 	err = nla_parse_nested(tb, TCA_GRED_MAX, opt, gred_policy, NULL);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index d04068a97d81..94db20352f37 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1396,7 +1396,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
 
 	qdisc_watchdog_init(&q->watchdog, sch);
 
-	if (opt == NULL || nla_len(opt) < sizeof(*qopt))
+	if (!opt || nla_len(opt) < sizeof(*qopt))
 		return -EINVAL;
 	qopt = nla_data(opt);
 
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 012216386c0b..37195e0c64ba 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -243,7 +243,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
 
 	q->queues = NULL;
 
-	if (opt == NULL)
+	if (!opt)
 		return -EINVAL;
 
 	err = tcf_block_get(&q->block, &q->filter_list, sch);
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 120f4f365967..e8f3345674c5 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -428,7 +428,7 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt)
 	qdisc_watchdog_init(&q->watchdog, sch);
 	q->qdisc = &noop_qdisc;
 
-	if (opt == NULL)
+	if (!opt)
 		return -EINVAL;
 
 	q->t_c = ktime_get_ns();
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 01/15] net: sched: fix coding style issues Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 19:45   ` David Ahern
  2017-12-14 18:38 ` [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors Alexander Aring
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs; +Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring

This patch sets a generic netlink error message if the validation of the
netlink attribute failed. It avoids several different settings of
netlink messages by handle nla_parse_nested on error case.

Suggested-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 lib/nlattr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/nlattr.c b/lib/nlattr.c
index dfa55c873c13..a2a9506b2fb7 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -253,8 +253,10 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
 			if (policy) {
 				err = validate_nla(nla, maxtype, policy);
 				if (err < 0) {
-					if (extack)
+					if (extack) {
+						NL_SET_ERR_MSG(extack, "Failed to validate netlink attribute");
 						extack->bad_attr = nla;
+					}
 					goto errout;
 				}
 			}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 01/15] net: sched: fix coding style issues Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:52   ` Alexander Aring
  2017-12-14 19:56   ` David Ahern
  2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for generic qdisc handling. The extack
will be set deeper to each called function which is not part of netdev
core api.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 net/sched/sch_api.c | 159 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 112 insertions(+), 47 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index b54917f4ad87..3ff59433781b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -449,7 +449,8 @@ static const struct nla_policy stab_policy[TCA_STAB_MAX + 1] = {
 	[TCA_STAB_DATA] = { .type = NLA_BINARY },
 };
 
-static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
+static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt,
+					       struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[TCA_STAB_MAX + 1];
 	struct qdisc_size_table *stab;
@@ -458,23 +459,29 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
 	u16 *tab = NULL;
 	int err;
 
-	err = nla_parse_nested(tb, TCA_STAB_MAX, opt, stab_policy, NULL);
+	err = nla_parse_nested(tb, TCA_STAB_MAX, opt, stab_policy, extack);
 	if (err < 0)
 		return ERR_PTR(err);
-	if (!tb[TCA_STAB_BASE])
+	if (!tb[TCA_STAB_BASE]) {
+		NL_SET_ERR_MSG(extack, "Size table base attribute is missing");
 		return ERR_PTR(-EINVAL);
+	}
 
 	s = nla_data(tb[TCA_STAB_BASE]);
 
 	if (s->tsize > 0) {
-		if (!tb[TCA_STAB_DATA])
+		if (!tb[TCA_STAB_DATA]) {
+			NL_SET_ERR_MSG(extack, "Size table data attribute is missing");
 			return ERR_PTR(-EINVAL);
+		}
 		tab = nla_data(tb[TCA_STAB_DATA]);
 		tsize = nla_len(tb[TCA_STAB_DATA]) / sizeof(u16);
 	}
 
-	if (tsize != s->tsize || (!tab && tsize > 0))
+	if (tsize != s->tsize || (!tab && tsize > 0)) {
+		NL_SET_ERR_MSG(extack, "Invalid size of size table");
 		return ERR_PTR(-EINVAL);
+	}
 
 	list_for_each_entry(stab, &qdisc_stab_list, list) {
 		if (memcmp(&stab->szopts, s, sizeof(*s)))
@@ -897,7 +904,8 @@ static void notify_and_destroy(struct net *net, struct sk_buff *skb,
 
 static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		       struct sk_buff *skb, struct nlmsghdr *n, u32 classid,
-		       struct Qdisc *new, struct Qdisc *old)
+		       struct Qdisc *new, struct Qdisc *old,
+		       struct netlink_ext_ack *extack)
 {
 	struct Qdisc *q = old;
 	struct net *net = dev_net(dev);
@@ -912,8 +920,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		    (new && new->flags & TCQ_F_INGRESS)) {
 			num_q = 1;
 			ingress = 1;
-			if (!dev_ingress_queue(dev))
+			if (!dev_ingress_queue(dev)) {
+				NL_SET_ERR_MSG(extack, "Cannot find ingress queue for specified device");
 				return -ENOENT;
+			}
 		}
 
 		if (dev->flags & IFF_UP)
@@ -964,10 +974,12 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 		if (cops && cops->graft) {
 			unsigned long cl = cops->find(parent, classid);
 
-			if (cl)
+			if (cl) {
 				err = cops->graft(parent, cl, new, &old);
-			else
+			} else {
+				NL_SET_ERR_MSG(extack, "Specified class not found");
 				err = -ENOENT;
+			}
 		}
 		if (!err)
 			notify_and_destroy(net, skb, n, classid, old, new);
@@ -988,7 +1000,8 @@ static struct lock_class_key qdisc_rx_lock;
 static struct Qdisc *qdisc_create(struct net_device *dev,
 				  struct netdev_queue *dev_queue,
 				  struct Qdisc *p, u32 parent, u32 handle,
-				  struct nlattr **tca, int *errp)
+				  struct nlattr **tca, int *errp,
+				  struct netlink_ext_ack *extack)
 {
 	int err;
 	struct nlattr *kind = tca[TCA_KIND];
@@ -1026,14 +1039,15 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 #endif
 
 	err = -ENOENT;
-	if (!ops)
+	if (!ops) {
+		NL_SET_ERR_MSG(extack, "Specified qdisc not found");
 		goto err_out;
+	}
 
 	sch = qdisc_alloc(dev_queue, ops);
-	if (IS_ERR(sch)) {
+	if (IS_ERR(sch))
 		err = PTR_ERR(sch);
 		goto err_out2;
-	}
 
 	sch->parent = parent;
 
@@ -1084,7 +1098,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 	}
 
 	if (tca[TCA_STAB]) {
-		stab = qdisc_get_stab(tca[TCA_STAB]);
+		stab = qdisc_get_stab(tca[TCA_STAB], extack);
 		if (IS_ERR(stab)) {
 			err = PTR_ERR(stab);
 			goto err_out4;
@@ -1095,8 +1109,10 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 		seqcount_t *running;
 
 		err = -EOPNOTSUPP;
-		if (sch->flags & TCQ_F_MQROOT)
+		if (sch->flags & TCQ_F_MQROOT) {
+			NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
 			goto err_out4;
+		}
 
 		if (sch->parent != TC_H_ROOT &&
 		    !(sch->flags & TCQ_F_INGRESS) &&
@@ -1111,8 +1127,10 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 					NULL,
 					running,
 					tca[TCA_RATE]);
-		if (err)
+		if (err) {
+			NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
 			goto err_out4;
+		}
 	}
 
 	qdisc_hash_add(sch, false);
@@ -1145,21 +1163,24 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 	goto err_out3;
 }
 
-static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
+static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
+			struct netlink_ext_ack *extack)
 {
 	struct qdisc_size_table *ostab, *stab = NULL;
 	int err = 0;
 
 	if (tca[TCA_OPTIONS]) {
-		if (!sch->ops->change)
+		if (!sch->ops->change) {
+			NL_SET_ERR_MSG(extack, "Change operation not supported by specified qdisc");
 			return -EINVAL;
+		}
 		err = sch->ops->change(sch, tca[TCA_OPTIONS]);
 		if (err)
 			return err;
 	}
 
 	if (tca[TCA_STAB]) {
-		stab = qdisc_get_stab(tca[TCA_STAB]);
+		stab = qdisc_get_stab(tca[TCA_STAB], extack);
 		if (IS_ERR(stab))
 			return PTR_ERR(stab);
 	}
@@ -1241,8 +1262,10 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 	int err;
 
 	if ((n->nlmsg_type != RTM_GETQDISC) &&
-	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
+	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
+		NL_SET_ERR_MSG(extack, "Net admin permission required for this operation");
 		return -EPERM;
+	}
 
 	err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL, extack);
 	if (err < 0)
@@ -1257,8 +1280,10 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 		if (clid != TC_H_ROOT) {
 			if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) {
 				p = qdisc_lookup(dev, TC_H_MAJ(clid));
-				if (!p)
+				if (!p) {
+					NL_SET_ERR_MSG(extack, "Failed to find qdisc with specified classid");
 					return -ENOENT;
+				}
 				q = qdisc_leaf(p, clid);
 			} else if (dev_ingress_queue(dev)) {
 				q = dev_ingress_queue(dev)->qdisc_sleeping;
@@ -1266,26 +1291,38 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 		} else {
 			q = dev->qdisc;
 		}
-		if (!q)
+		if (!q) {
+			NL_SET_ERR_MSG(extack, "Cannot find specified qdisc on specified device");
 			return -ENOENT;
+		}
 
-		if (tcm->tcm_handle && q->handle != tcm->tcm_handle)
+		if (tcm->tcm_handle && q->handle != tcm->tcm_handle) {
+			NL_SET_ERR_MSG(extack, "Invalid handle");
 			return -EINVAL;
+		}
 	} else {
 		q = qdisc_lookup(dev, tcm->tcm_handle);
-		if (!q)
+		if (!q) {
+			NL_SET_ERR_MSG(extack, "Failed to find qdisc with specified handle");
 			return -ENOENT;
+		}
 	}
 
-	if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
+	if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id)) {
+		NL_SET_ERR_MSG(extack, "Invalid qdisc name");
 		return -EINVAL;
+	}
 
 	if (n->nlmsg_type == RTM_DELQDISC) {
-		if (!clid)
+		if (!clid) {
+			NL_SET_ERR_MSG(extack, "Classid cannot be zero");
 			return -EINVAL;
-		if (q->handle == 0)
+		}
+		if (q->handle == 0) {
+			NL_SET_ERR_MSG(extack, "Cannot delete qdisc with handle of zero");
 			return -ENOENT;
-		err = qdisc_graft(dev, p, skb, n, clid, NULL, q);
+		}
+		err = qdisc_graft(dev, p, skb, n, clid, NULL, q, extack);
 		if (err != 0)
 			return err;
 	} else {
@@ -1309,8 +1346,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 	struct Qdisc *q, *p;
 	int err;
 
-	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
+	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
+		NL_SET_ERR_MSG(extack, "Net admin permission required for this operation");
 		return -EPERM;
+	}
 
 replay:
 	/* Reinit, just in case something touches this. */
@@ -1331,8 +1370,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 		if (clid != TC_H_ROOT) {
 			if (clid != TC_H_INGRESS) {
 				p = qdisc_lookup(dev, TC_H_MAJ(clid));
-				if (!p)
+				if (!p) {
+					NL_SET_ERR_MSG(extack, "Failed to find specified qdisc");
 					return -ENOENT;
+				}
 				q = qdisc_leaf(p, clid);
 			} else if (dev_ingress_queue_create(dev)) {
 				q = dev_ingress_queue(dev)->qdisc_sleeping;
@@ -1347,21 +1388,33 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 
 		if (!q || !tcm->tcm_handle || q->handle != tcm->tcm_handle) {
 			if (tcm->tcm_handle) {
-				if (q && !(n->nlmsg_flags & NLM_F_REPLACE))
+				if (q && !(n->nlmsg_flags & NLM_F_REPLACE)) {
+					NL_SET_ERR_MSG(extack, "NLM_F_REPLACE needed to override");
 					return -EEXIST;
-				if (TC_H_MIN(tcm->tcm_handle))
+				}
+				if (TC_H_MIN(tcm->tcm_handle)) {
+					NL_SET_ERR_MSG(extack, "Invalid minor handle");
 					return -EINVAL;
+				}
 				q = qdisc_lookup(dev, tcm->tcm_handle);
-				if (!q)
+				if (!q) {
+					NL_SET_ERR_MSG(extack, "No qdisc found for specified handle");
 					goto create_n_graft;
-				if (n->nlmsg_flags & NLM_F_EXCL)
+				}
+				if (n->nlmsg_flags & NLM_F_EXCL) {
+					NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot override");
 					return -EEXIST;
+				}
 				if (tca[TCA_KIND] &&
-				    nla_strcmp(tca[TCA_KIND], q->ops->id))
+				    nla_strcmp(tca[TCA_KIND], q->ops->id)) {
+					NL_SET_ERR_MSG(extack, "Invalid qdisc name");
 					return -EINVAL;
+				}
 				if (q == p ||
-				    (p && check_loop(q, p, 0)))
+				    (p && check_loop(q, p, 0))) {
+					NL_SET_ERR_MSG(extack, "Qdisc parent/child loop detected");
 					return -ELOOP;
+				}
 				qdisc_refcount_inc(q);
 				goto graft;
 			} else {
@@ -1396,33 +1449,45 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 			}
 		}
 	} else {
-		if (!tcm->tcm_handle)
+		if (!tcm->tcm_handle) {
+			NL_SET_ERR_MSG(extack, "Handle cannot be zero");
 			return -EINVAL;
+		}
 		q = qdisc_lookup(dev, tcm->tcm_handle);
 	}
 
 	/* Change qdisc parameters */
-	if (!q)
+	if (!q) {
+		NL_SET_ERR_MSG(extack, "Specified qdisc not found");
 		return -ENOENT;
-	if (n->nlmsg_flags & NLM_F_EXCL)
+	}
+	if (n->nlmsg_flags & NLM_F_EXCL) {
+		NL_SET_ERR_MSG(extack, "Exclusivity flag on, cannot modify");
 		return -EEXIST;
-	if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
+	}
+	if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id)) {
+		NL_SET_ERR_MSG(extack, "Invalid qdisc name");
 		return -EINVAL;
-	err = qdisc_change(q, tca);
+	}
+	err = qdisc_change(q, tca, extack);
 	if (err == 0)
 		qdisc_notify(net, skb, n, clid, NULL, q);
 	return err;
 
 create_n_graft:
-	if (!(n->nlmsg_flags & NLM_F_CREATE))
+	if (!(n->nlmsg_flags & NLM_F_CREATE)) {
+		NL_SET_ERR_MSG(extack, "Qdisc not found. To create specify NLM_F_CREATE flag");
 		return -ENOENT;
+	}
 	if (clid == TC_H_INGRESS) {
-		if (dev_ingress_queue(dev))
+		if (dev_ingress_queue(dev)) {
 			q = qdisc_create(dev, dev_ingress_queue(dev), p,
 					 tcm->tcm_parent, tcm->tcm_parent,
-					 tca, &err);
-		else
+					 tca, &err, extack);
+		} else {
+			NL_SET_ERR_MSG(extack, "Cannot find ingress queue for specified device");
 			err = -ENOENT;
+		}
 	} else {
 		struct netdev_queue *dev_queue;
 
@@ -1435,7 +1500,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 
 		q = qdisc_create(dev, dev_queue, p,
 				 tcm->tcm_parent, tcm->tcm_handle,
-				 tca, &err);
+				 tca, &err, extack);
 	}
 	if (q == NULL) {
 		if (err == -EAGAIN)
@@ -1444,7 +1509,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
 	}
 
 graft:
-	err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
+	err = qdisc_graft(dev, p, skb, n, clid, q, NULL, extack);
 	if (err) {
 		if (q)
 			qdisc_destroy(q);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (2 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-16 19:08   ` kbuild test robot
                     ` (2 more replies)
  2017-12-14 18:38 ` [PATCHv2 net-next 05/15] net: sched: sch: add extack for change qdisc ops Alexander Aring
                   ` (10 subsequent siblings)
  14 siblings, 3 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for init callback to prepare per-qdisc
specific changes for extack.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h |  3 ++-
 net/sched/sch_api.c       |  2 +-
 net/sched/sch_cbq.c       |  3 ++-
 net/sched/sch_cbs.c       |  3 ++-
 net/sched/sch_choke.c     |  3 ++-
 net/sched/sch_codel.c     |  3 ++-
 net/sched/sch_drr.c       |  3 ++-
 net/sched/sch_dsmark.c    |  3 ++-
 net/sched/sch_fifo.c      | 14 ++++++++++----
 net/sched/sch_fq.c        |  3 ++-
 net/sched/sch_fq_codel.c  |  3 ++-
 net/sched/sch_generic.c   |  8 +++++---
 net/sched/sch_gred.c      |  3 ++-
 net/sched/sch_hfsc.c      |  3 ++-
 net/sched/sch_hhf.c       |  3 ++-
 net/sched/sch_htb.c       |  3 ++-
 net/sched/sch_ingress.c   |  6 ++++--
 net/sched/sch_mq.c        |  3 ++-
 net/sched/sch_mqprio.c    |  3 ++-
 net/sched/sch_multiq.c    |  3 ++-
 net/sched/sch_netem.c     |  3 ++-
 net/sched/sch_pie.c       |  3 ++-
 net/sched/sch_plug.c      |  3 ++-
 net/sched/sch_prio.c      |  3 ++-
 net/sched/sch_qfq.c       |  3 ++-
 net/sched/sch_red.c       |  3 ++-
 net/sched/sch_sfb.c       |  3 ++-
 net/sched/sch_sfq.c       |  3 ++-
 net/sched/sch_tbf.c       |  3 ++-
 net/sched/sch_teql.c      |  3 ++-
 30 files changed, 72 insertions(+), 36 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 8f8c0afe529b..0f1c4b3a6cb7 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -188,7 +188,8 @@ struct Qdisc_ops {
 	struct sk_buff *	(*dequeue)(struct Qdisc *);
 	struct sk_buff *	(*peek)(struct Qdisc *);
 
-	int			(*init)(struct Qdisc *sch, struct nlattr *arg);
+	int			(*init)(struct Qdisc *sch, struct nlattr *arg,
+					struct netlink_ext_ack *extack);
 	void			(*reset)(struct Qdisc *);
 	void			(*destroy)(struct Qdisc *);
 	int			(*change)(struct Qdisc *sch,
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 3ff59433781b..07c29461009f 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1081,7 +1081,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 	}
 
 	if (ops->init) {
-		err = ops->init(sch, tca[TCA_OPTIONS]);
+		err = ops->init(sch, tca[TCA_OPTIONS], extack);
 		if (err != 0)
 			goto err_out5;
 	}
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 0692fe35f4ec..86eba01457f3 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1132,7 +1132,8 @@ static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
 	[TCA_CBQ_POLICE]	= { .len = sizeof(struct tc_cbq_police) },
 };
 
-static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
+static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_CBQ_MAX + 1];
diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
index 7a72980c1509..d77c632a276c 100644
--- a/net/sched/sch_cbs.c
+++ b/net/sched/sch_cbs.c
@@ -291,7 +291,8 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int cbs_init(struct Qdisc *sch, struct nlattr *opt)
+static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct cbs_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index 531250fceb9e..49dda301e3bb 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -431,7 +431,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int choke_init(struct Qdisc *sch, struct nlattr *opt)
+static int choke_init(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	return choke_change(sch, opt);
 }
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
index c518a1efcb9d..7221244e7f3b 100644
--- a/net/sched/sch_codel.c
+++ b/net/sched/sch_codel.c
@@ -184,7 +184,8 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int codel_init(struct Qdisc *sch, struct nlattr *opt)
+static int codel_init(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct codel_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 5bbcef3dcd8c..1a88473cd768 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -408,7 +408,8 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
 	return NULL;
 }
 
-static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
+			  struct netlink_ext_ack *extack)
 {
 	struct drr_sched *q = qdisc_priv(sch);
 	int err;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index fb4fb71c68cf..16dd480b5583 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -330,7 +330,8 @@ static struct sk_buff *dsmark_peek(struct Qdisc *sch)
 	return p->q->ops->peek(p->q);
 }
 
-static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
+static int dsmark_init(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
 	struct nlattr *tb[TCA_DSMARK_MAX + 1];
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 1e37247656f8..a2d1c9f9b798 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -55,7 +55,8 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 	return NET_XMIT_CN;
 }
 
-static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
+static int fifo_init(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	bool bypass;
 	bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
@@ -88,6 +89,11 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
+static int fifo_change(struct Qdisc *sch, struct nlattr *opt)
+{
+	return fifo_init(sch, opt, NULL);
+}
+
 static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct tc_fifo_qopt opt = { .limit = sch->limit };
@@ -108,7 +114,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_init,
+	.change		=	fifo_change,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
@@ -122,7 +128,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_init,
+	.change		=	fifo_change,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
@@ -136,7 +142,7 @@ struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_init,
+	.change		=	fifo_change,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index 263d16e3219e..c9f61ffe220e 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -788,7 +788,8 @@ static void fq_destroy(struct Qdisc *sch)
 	qdisc_watchdog_cancel(&q->watchdog);
 }
 
-static int fq_init(struct Qdisc *sch, struct nlattr *opt)
+static int fq_init(struct Qdisc *sch, struct nlattr *opt,
+		   struct netlink_ext_ack *extack)
 {
 	struct fq_sched_data *q = qdisc_priv(sch);
 	int err;
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 0305d791ea94..5d0b20898ffa 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -458,7 +458,8 @@ static void fq_codel_destroy(struct Qdisc *sch)
 	kvfree(q->flows);
 }
 
-static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt)
+static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
+			 struct netlink_ext_ack *extack)
 {
 	struct fq_codel_sched_data *q = qdisc_priv(sch);
 	int i;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 981c08fe810b..5cdafe88b902 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -551,7 +551,8 @@ struct Qdisc noop_qdisc = {
 };
 EXPORT_SYMBOL(noop_qdisc);
 
-static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt)
+static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt,
+			struct netlink_ext_ack *extack)
 {
 	/* register_qdisc() assigns a default of noop_enqueue if unset,
 	 * but __dev_queue_xmit() treats noqueue only as such
@@ -684,7 +685,8 @@ static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
 	return -1;
 }
 
-static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
+static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt,
+			   struct netlink_ext_ack *extack)
 {
 	unsigned int qlen = qdisc_dev(qdisc)->tx_queue_len;
 	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
@@ -834,7 +836,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
 	}
 	sch->parent = parentid;
 
-	if (!ops->init || ops->init(sch, NULL) == 0)
+	if (!ops->init || ops->init(sch, NULL, NULL) == 0)
 		return sch;
 
 	qdisc_destroy(sch);
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index ccd1a00e2a9a..4cab6ccad643 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -466,7 +466,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
 	return err;
 }
 
-static int gred_init(struct Qdisc *sch, struct nlattr *opt)
+static int gred_init(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[TCA_GRED_MAX + 1];
 	int err;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 94db20352f37..1102943c46c9 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1388,7 +1388,8 @@ hfsc_schedule_watchdog(struct Qdisc *sch)
 }
 
 static int
-hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
+		struct netlink_ext_ack *extack)
 {
 	struct hfsc_sched *q = qdisc_priv(sch);
 	struct tc_hfsc_qopt *qopt;
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index 73a53c08091b..b3a80f0ed4b0 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -571,7 +571,8 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int hhf_init(struct Qdisc *sch, struct nlattr *opt)
+static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct hhf_sched_data *q = qdisc_priv(sch);
 	int i;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index fa0380730ff0..41d9b7da9273 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1017,7 +1017,8 @@ static void htb_work_func(struct work_struct *work)
 	rcu_read_unlock();
 }
 
-static int htb_init(struct Qdisc *sch, struct nlattr *opt)
+static int htb_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct htb_sched *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_HTB_MAX + 1];
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index 5ecc38f35d47..c703cf3a0bed 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -62,7 +62,8 @@ static void clsact_chain_head_change(struct tcf_proto *tp_head, void *priv)
 	mini_qdisc_pair_swap(miniqp, tp_head);
 }
 
-static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
+static int ingress_init(struct Qdisc *sch, struct nlattr *opt,
+			struct netlink_ext_ack *extack)
 {
 	struct ingress_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
@@ -166,7 +167,8 @@ static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl)
 	}
 }
 
-static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
+static int clsact_init(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct clsact_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index 8cbb5c829d59..b91f7d8cb184 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -36,7 +36,8 @@ static void mq_destroy(struct Qdisc *sch)
 	kfree(priv->qdiscs);
 }
 
-static int mq_init(struct Qdisc *sch, struct nlattr *opt)
+static int mq_init(struct Qdisc *sch, struct nlattr *opt,
+		   struct netlink_ext_ack *extack)
 {
 	struct net_device *dev = qdisc_dev(sch);
 	struct mq_sched *priv = qdisc_priv(sch);
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 8622745f3cd9..0379fc4ee7bb 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -132,7 +132,8 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
 	return 0;
 }
 
-static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
+static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct net_device *dev = qdisc_dev(sch);
 	struct mqprio_sched *priv = qdisc_priv(sch);
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 37195e0c64ba..54132dde6d42 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -236,7 +236,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
+static int multiq_init(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct multiq_sched_data *q = qdisc_priv(sch);
 	int i, err;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index dd70924cbcdf..6490ce08d29e 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -984,7 +984,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
 	return ret;
 }
 
-static int netem_init(struct Qdisc *sch, struct nlattr *opt)
+static int netem_init(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 	int ret;
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index 776c694c77c7..c4c87ed3971f 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -439,7 +439,8 @@ static void pie_timer(struct timer_list *t)
 
 }
 
-static int pie_init(struct Qdisc *sch, struct nlattr *opt)
+static int pie_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct pie_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_plug.c b/net/sched/sch_plug.c
index 1c6cbab3e7b9..d9c6fbe55ae5 100644
--- a/net/sched/sch_plug.c
+++ b/net/sched/sch_plug.c
@@ -123,7 +123,8 @@ static struct sk_buff *plug_dequeue(struct Qdisc *sch)
 	return qdisc_dequeue_head(sch);
 }
 
-static int plug_init(struct Qdisc *sch, struct nlattr *opt)
+static int plug_init(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	struct plug_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 2c79559a0d31..8632d795e6ee 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -205,7 +205,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int prio_init(struct Qdisc *sch, struct nlattr *opt)
+static int prio_init(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 	int err;
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 6962b37a3ad3..7c1b976314bd 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -1413,7 +1413,8 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
 	qfq_deactivate_class(q, cl);
 }
 
-static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
+			  struct netlink_ext_ack *extack)
 {
 	struct qfq_sched *q = qdisc_priv(sch);
 	struct qfq_group *grp;
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 9d874e60e032..e7fb68613f4d 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -264,7 +264,8 @@ static inline void red_adaptative_timer(struct timer_list *t)
 	spin_unlock(root_lock);
 }
 
-static int red_init(struct Qdisc *sch, struct nlattr *opt)
+static int red_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 0678debdd856..b2205eaa0f51 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -549,7 +549,8 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt)
 	return 0;
 }
 
-static int sfb_init(struct Qdisc *sch, struct nlattr *opt)
+static int sfb_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct sfb_sched_data *q = qdisc_priv(sch);
 	int err;
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 930e5bd26d3d..3b5869c7b3f3 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -721,7 +721,8 @@ static void sfq_destroy(struct Qdisc *sch)
 	kfree(q->red_parms);
 }
 
-static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
+static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct sfq_sched_data *q = qdisc_priv(sch);
 	int i;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index e8f3345674c5..9abff1271ec0 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -421,7 +421,8 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
 	return err;
 }
 
-static int tbf_init(struct Qdisc *sch, struct nlattr *opt)
+static int tbf_init(struct Qdisc *sch, struct nlattr *opt,
+		    struct netlink_ext_ack *extack)
 {
 	struct tbf_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 9fe6b427afed..93f04cf5cac1 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -167,7 +167,8 @@ teql_destroy(struct Qdisc *sch)
 	}
 }
 
-static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
+static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt,
+			   struct netlink_ext_ack *extack)
 {
 	struct net_device *dev = qdisc_dev(sch);
 	struct teql_master *m = (struct teql_master *)sch->ops;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 05/15] net: sched: sch: add extack for change qdisc ops
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (3 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 06/15] net: sched: sch: add extack to change class Alexander Aring
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for change callback for qdisc ops
structtur to prepare per-qdisc specific changes for extack.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h |  3 ++-
 net/sched/sch_api.c       |  2 +-
 net/sched/sch_cbs.c       |  5 +++--
 net/sched/sch_choke.c     |  5 +++--
 net/sched/sch_codel.c     |  5 +++--
 net/sched/sch_fifo.c      | 13 ++++---------
 net/sched/sch_fq.c        |  5 +++--
 net/sched/sch_fq_codel.c  |  5 +++--
 net/sched/sch_gred.c      |  3 ++-
 net/sched/sch_hfsc.c      |  3 ++-
 net/sched/sch_hhf.c       |  5 +++--
 net/sched/sch_multiq.c    |  5 +++--
 net/sched/sch_netem.c     |  5 +++--
 net/sched/sch_pie.c       |  5 +++--
 net/sched/sch_plug.c      |  3 ++-
 net/sched/sch_prio.c      |  5 +++--
 net/sched/sch_red.c       |  5 +++--
 net/sched/sch_sfb.c       |  5 +++--
 net/sched/sch_tbf.c       |  5 +++--
 19 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 0f1c4b3a6cb7..7f35e71a478b 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -193,7 +193,8 @@ struct Qdisc_ops {
 	void			(*reset)(struct Qdisc *);
 	void			(*destroy)(struct Qdisc *);
 	int			(*change)(struct Qdisc *sch,
-					  struct nlattr *arg);
+					  struct nlattr *arg,
+					  struct netlink_ext_ack *extack);
 	void			(*attach)(struct Qdisc *sch);
 
 	int			(*dump)(struct Qdisc *, struct sk_buff *);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 07c29461009f..5344fe0f4e42 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1174,7 +1174,7 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
 			NL_SET_ERR_MSG(extack, "Change operation not supported by specified qdisc");
 			return -EINVAL;
 		}
-		err = sch->ops->change(sch, tca[TCA_OPTIONS]);
+		err = sch->ops->change(sch, tca[TCA_OPTIONS], extack);
 		if (err)
 			return err;
 	}
diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
index d77c632a276c..8bf6e163d29c 100644
--- a/net/sched/sch_cbs.c
+++ b/net/sched/sch_cbs.c
@@ -246,7 +246,8 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
 	return 0;
 }
 
-static int cbs_change(struct Qdisc *sch, struct nlattr *opt)
+static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct cbs_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
@@ -307,7 +308,7 @@ static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
 
 	qdisc_watchdog_init(&q->watchdog, sch);
 
-	return cbs_change(sch, opt);
+	return cbs_change(sch, opt, extack);
 }
 
 static void cbs_destroy(struct Qdisc *sch)
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index 49dda301e3bb..eafc0d17d174 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -344,7 +344,8 @@ static void choke_free(void *addr)
 	kvfree(addr);
 }
 
-static int choke_change(struct Qdisc *sch, struct nlattr *opt)
+static int choke_change(struct Qdisc *sch, struct nlattr *opt,
+			struct netlink_ext_ack *extack)
 {
 	struct choke_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_CHOKE_MAX + 1];
@@ -434,7 +435,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
 static int choke_init(struct Qdisc *sch, struct nlattr *opt,
 		      struct netlink_ext_ack *extack)
 {
-	return choke_change(sch, opt);
+	return choke_change(sch, opt, extack);
 }
 
 static int choke_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
index 7221244e7f3b..17cd81f84b5d 100644
--- a/net/sched/sch_codel.c
+++ b/net/sched/sch_codel.c
@@ -130,7 +130,8 @@ static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = {
 	[TCA_CODEL_CE_THRESHOLD]= { .type = NLA_U32 },
 };
 
-static int codel_change(struct Qdisc *sch, struct nlattr *opt)
+static int codel_change(struct Qdisc *sch, struct nlattr *opt,
+			struct netlink_ext_ack *extack)
 {
 	struct codel_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_CODEL_MAX + 1];
@@ -197,7 +198,7 @@ static int codel_init(struct Qdisc *sch, struct nlattr *opt,
 	q->params.mtu = psched_mtu(qdisc_dev(sch));
 
 	if (opt) {
-		int err = codel_change(sch, opt);
+		int err = codel_change(sch, opt, extack);
 
 		if (err)
 			return err;
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index a2d1c9f9b798..c65f23c70f40 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -89,11 +89,6 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt,
 	return 0;
 }
 
-static int fifo_change(struct Qdisc *sch, struct nlattr *opt)
-{
-	return fifo_init(sch, opt, NULL);
-}
-
 static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct tc_fifo_qopt opt = { .limit = sch->limit };
@@ -114,7 +109,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_change,
+	.change		=	fifo_init,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
@@ -128,7 +123,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_change,
+	.change		=	fifo_init,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
@@ -142,7 +137,7 @@ struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
 	.peek		=	qdisc_peek_head,
 	.init		=	fifo_init,
 	.reset		=	qdisc_reset_queue,
-	.change		=	fifo_change,
+	.change		=	fifo_init,
 	.dump		=	fifo_dump,
 	.owner		=	THIS_MODULE,
 };
@@ -163,7 +158,7 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit)
 		nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt));
 		((struct tc_fifo_qopt *)nla_data(nla))->limit = limit;
 
-		ret = q->ops->change(q, nla);
+		ret = q->ops->change(q, nla, NULL);
 		kfree(nla);
 	}
 	return ret;
diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
index c9f61ffe220e..a366e4c9413a 100644
--- a/net/sched/sch_fq.c
+++ b/net/sched/sch_fq.c
@@ -685,7 +685,8 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
 	[TCA_FQ_LOW_RATE_THRESHOLD]	= { .type = NLA_U32 },
 };
 
-static int fq_change(struct Qdisc *sch, struct nlattr *opt)
+static int fq_change(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	struct fq_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_FQ_MAX + 1];
@@ -812,7 +813,7 @@ static int fq_init(struct Qdisc *sch, struct nlattr *opt,
 	qdisc_watchdog_init(&q->watchdog, sch);
 
 	if (opt)
-		err = fq_change(sch, opt);
+		err = fq_change(sch, opt, extack);
 	else
 		err = fq_resize(sch, q->fq_trees_log);
 
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 5d0b20898ffa..d798c93f7c96 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -377,7 +377,8 @@ static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = {
 	[TCA_FQ_CODEL_MEMORY_LIMIT] = { .type = NLA_U32 },
 };
 
-static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt)
+static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
+			   struct netlink_ext_ack *extack)
 {
 	struct fq_codel_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_FQ_CODEL_MAX + 1];
@@ -478,7 +479,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
 	q->cparams.mtu = psched_mtu(qdisc_dev(sch));
 
 	if (opt) {
-		int err = fq_codel_change(sch, opt);
+		int err = fq_codel_change(sch, opt, NULL);
 		if (err)
 			return err;
 	}
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 4cab6ccad643..cbe4831f46f4 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -392,7 +392,8 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = {
 	[TCA_GRED_LIMIT]	= { .type = NLA_U32 },
 };
 
-static int gred_change(struct Qdisc *sch, struct nlattr *opt)
+static int gred_change(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct gred_sched *table = qdisc_priv(sch);
 	struct tc_gred_qopt *ctl;
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 1102943c46c9..f49a4a4fe095 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1430,7 +1430,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
 }
 
 static int
-hfsc_change_qdisc(struct Qdisc *sch, struct nlattr *opt)
+hfsc_change_qdisc(struct Qdisc *sch, struct nlattr *opt,
+		  struct netlink_ext_ack *extack)
 {
 	struct hfsc_sched *q = qdisc_priv(sch);
 	struct tc_hfsc_qopt *qopt;
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index b3a80f0ed4b0..bce2632212d3 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -504,7 +504,8 @@ static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {
 	[TCA_HHF_NON_HH_WEIGHT]	 = { .type = NLA_U32 },
 };
 
-static int hhf_change(struct Qdisc *sch, struct nlattr *opt)
+static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct hhf_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_HHF_MAX + 1];
@@ -590,7 +591,7 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
 	q->hhf_non_hh_weight = 2;
 
 	if (opt) {
-		int err = hhf_change(sch, opt);
+		int err = hhf_change(sch, opt, extack);
 
 		if (err)
 			return err;
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 54132dde6d42..a8db1dbeb04f 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -180,7 +180,8 @@ multiq_destroy(struct Qdisc *sch)
 	kfree(q->queues);
 }
 
-static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
+static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct multiq_sched_data *q = qdisc_priv(sch);
 	struct tc_multiq_qopt *qopt;
@@ -259,7 +260,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt,
 	for (i = 0; i < q->max_bands; i++)
 		q->queues[i] = &noop_qdisc;
 
-	return multiq_tune(sch, opt);
+	return multiq_tune(sch, opt, extack);
 }
 
 static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 6490ce08d29e..f45040b55531 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -893,7 +893,8 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
 }
 
 /* Parse netlink message to set options */
-static int netem_change(struct Qdisc *sch, struct nlattr *opt)
+static int netem_change(struct Qdisc *sch, struct nlattr *opt,
+			struct netlink_ext_ack *extack)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_NETEM_MAX + 1];
@@ -996,7 +997,7 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt,
 		return -EINVAL;
 
 	q->loss_model = CLG_RANDOM;
-	ret = netem_change(sch, opt);
+	ret = netem_change(sch, opt, extack);
 	if (ret)
 		pr_info("netem: change failed\n");
 	return ret;
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index c4c87ed3971f..18d30bb86881 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -181,7 +181,8 @@ static const struct nla_policy pie_policy[TCA_PIE_MAX + 1] = {
 	[TCA_PIE_BYTEMODE] = {.type = NLA_U32},
 };
 
-static int pie_change(struct Qdisc *sch, struct nlattr *opt)
+static int pie_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct pie_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_PIE_MAX + 1];
@@ -452,7 +453,7 @@ static int pie_init(struct Qdisc *sch, struct nlattr *opt,
 	timer_setup(&q->adapt_timer, pie_timer, 0);
 
 	if (opt) {
-		int err = pie_change(sch, opt);
+		int err = pie_change(sch, opt, extack);
 
 		if (err)
 			return err;
diff --git a/net/sched/sch_plug.c b/net/sched/sch_plug.c
index d9c6fbe55ae5..5619d2eb17b6 100644
--- a/net/sched/sch_plug.c
+++ b/net/sched/sch_plug.c
@@ -159,7 +159,8 @@ static int plug_init(struct Qdisc *sch, struct nlattr *opt,
  *   command is received (just act as a pass-thru queue).
  * TCQ_PLUG_LIMIT: Increase/decrease queue size
  */
-static int plug_change(struct Qdisc *sch, struct nlattr *opt)
+static int plug_change(struct Qdisc *sch, struct nlattr *opt,
+		       struct netlink_ext_ack *extack)
 {
 	struct plug_sched_data *q = qdisc_priv(sch);
 	struct tc_plug_qopt *msg;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 8632d795e6ee..5f8ecbaa2610 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -153,7 +153,8 @@ prio_destroy(struct Qdisc *sch)
 		qdisc_destroy(q->queues[prio]);
 }
 
-static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
+static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
+		     struct netlink_ext_ack *extack)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 	struct Qdisc *queues[TCQ_PRIO_BANDS];
@@ -218,7 +219,7 @@ static int prio_init(struct Qdisc *sch, struct nlattr *opt,
 	if (err)
 		return err;
 
-	return prio_tune(sch, opt);
+	return prio_tune(sch, opt, extack);
 }
 
 static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index e7fb68613f4d..66b33b829b54 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -189,7 +189,8 @@ static const struct nla_policy red_policy[TCA_RED_MAX + 1] = {
 	[TCA_RED_MAX_P] = { .type = NLA_U32 },
 };
 
-static int red_change(struct Qdisc *sch, struct nlattr *opt)
+static int red_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 	struct nlattr *tb[TCA_RED_MAX + 1];
@@ -272,7 +273,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt,
 	q->qdisc = &noop_qdisc;
 	q->sch = sch;
 	timer_setup(&q->adapt_timer, red_adaptative_timer, 0);
-	return red_change(sch, opt);
+	return red_change(sch, opt, extack);
 }
 
 static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt)
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index b2205eaa0f51..1b9d69bd6ed6 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -488,7 +488,8 @@ static const struct tc_sfb_qopt sfb_default_ops = {
 	.penalty_burst = 20,
 };
 
-static int sfb_change(struct Qdisc *sch, struct nlattr *opt)
+static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	struct sfb_sched_data *q = qdisc_priv(sch);
 	struct Qdisc *child;
@@ -560,7 +561,7 @@ static int sfb_init(struct Qdisc *sch, struct nlattr *opt,
 		return err;
 
 	q->qdisc = &noop_qdisc;
-	return sfb_change(sch, opt);
+	return sfb_change(sch, opt, extack);
 }
 
 static int sfb_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 9abff1271ec0..273228eb5ce0 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -302,7 +302,8 @@ static const struct nla_policy tbf_policy[TCA_TBF_MAX + 1] = {
 	[TCA_TBF_PBURST] = { .type = NLA_U32 },
 };
 
-static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
+static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
+		      struct netlink_ext_ack *extack)
 {
 	int err;
 	struct tbf_sched_data *q = qdisc_priv(sch);
@@ -434,7 +435,7 @@ static int tbf_init(struct Qdisc *sch, struct nlattr *opt,
 
 	q->t_c = ktime_get_ns();
 
-	return tbf_change(sch, opt);
+	return tbf_change(sch, opt, extack);
 }
 
 static void tbf_destroy(struct Qdisc *sch)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 06/15] net: sched: sch: add extack to change class
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (4 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 05/15] net: sched: sch: add extack for change qdisc ops Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 07/15] net: sched: sch: add extack for block callback Alexander Aring
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for class change callback api. This prepares
to handle extack support inside each specific class implementation.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h | 3 ++-
 net/sched/sch_api.c       | 2 +-
 net/sched/sch_atm.c       | 3 ++-
 net/sched/sch_cbq.c       | 2 +-
 net/sched/sch_drr.c       | 3 ++-
 net/sched/sch_dsmark.c    | 3 ++-
 net/sched/sch_fq_codel.c  | 2 +-
 net/sched/sch_hfsc.c      | 3 ++-
 net/sched/sch_htb.c       | 2 +-
 net/sched/sch_qfq.c       | 3 ++-
 net/sched/sch_sfb.c       | 3 ++-
 11 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 7f35e71a478b..219ad45cc4cd 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -157,7 +157,8 @@ struct Qdisc_class_ops {
 	/* Class manipulation routines */
 	unsigned long		(*find)(struct Qdisc *, u32 classid);
 	int			(*change)(struct Qdisc *, u32, u32,
-					struct nlattr **, unsigned long *);
+					struct nlattr **, unsigned long *,
+					struct netlink_ext_ack *);
 	int			(*delete)(struct Qdisc *, unsigned long);
 	void			(*walk)(struct Qdisc *, struct qdisc_walker * arg);
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 5344fe0f4e42..93171ac48443 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1908,7 +1908,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
 	new_cl = cl;
 	err = -EOPNOTSUPP;
 	if (cops->change)
-		err = cops->change(q, clid, portid, tca, &new_cl);
+		err = cops->change(q, clid, portid, tca, &new_cl, extack);
 	if (err == 0) {
 		tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS);
 		/* We just create a new class, need to do reverse binding. */
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 2dbd249c0b2f..07bffd1b537c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -191,7 +191,8 @@ static const struct nla_policy atm_policy[TCA_ATM_MAX + 1] = {
 };
 
 static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
-			 struct nlattr **tca, unsigned long *arg)
+			 struct nlattr **tca, unsigned long *arg,
+			 struct netlink_ext_ack *extack)
 {
 	struct atm_qdisc_data *p = qdisc_priv(sch);
 	struct atm_flow_data *flow = (struct atm_flow_data *)*arg;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 86eba01457f3..8f1832df8b4f 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1452,7 +1452,7 @@ static void cbq_destroy(struct Qdisc *sch)
 
 static int
 cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **tca,
-		 unsigned long *arg)
+		 unsigned long *arg, struct netlink_ext_ack *extack)
 {
 	int err;
 	struct cbq_sched_data *q = qdisc_priv(sch);
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 1a88473cd768..73b914bc47a4 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -64,7 +64,8 @@ static const struct nla_policy drr_policy[TCA_DRR_MAX + 1] = {
 };
 
 static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
+			    struct nlattr **tca, unsigned long *arg,
+			    struct netlink_ext_ack *extack)
 {
 	struct drr_sched *q = qdisc_priv(sch);
 	struct drr_class *cl = (struct drr_class *)*arg;
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 16dd480b5583..89e433bbd590 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -112,7 +112,8 @@ static const struct nla_policy dsmark_policy[TCA_DSMARK_MAX + 1] = {
 };
 
 static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent,
-			 struct nlattr **tca, unsigned long *arg)
+			 struct nlattr **tca, unsigned long *arg,
+			 struct netlink_ext_ack *extack)
 {
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
 	struct nlattr *opt = tca[TCA_OPTIONS];
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index d798c93f7c96..b4ca46aafb5a 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -479,7 +479,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
 	q->cparams.mtu = psched_mtu(qdisc_dev(sch));
 
 	if (opt) {
-		int err = fq_codel_change(sch, opt, NULL);
+		int err = fq_codel_change(sch, opt, extack);
 		if (err)
 			return err;
 	}
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index f49a4a4fe095..11410b0e4068 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -921,7 +921,8 @@ static const struct nla_policy hfsc_policy[TCA_HFSC_MAX + 1] = {
 
 static int
 hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-		  struct nlattr **tca, unsigned long *arg)
+		  struct nlattr **tca, unsigned long *arg,
+		  struct netlink_ext_ack *extack)
 {
 	struct hfsc_sched *q = qdisc_priv(sch);
 	struct hfsc_class *cl = (struct hfsc_class *)*arg;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 41d9b7da9273..eb535a23a69b 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1327,7 +1327,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
 
 static int htb_change_class(struct Qdisc *sch, u32 classid,
 			    u32 parentid, struct nlattr **tca,
-			    unsigned long *arg)
+			    unsigned long *arg, struct netlink_ext_ack *extack)
 {
 	int err = -EINVAL;
 	struct htb_sched *q = qdisc_priv(sch);
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 7c1b976314bd..1f4a84b687d2 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -402,7 +402,8 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight,
 }
 
 static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
+			    struct nlattr **tca, unsigned long *arg,
+			    struct netlink_ext_ack *extack)
 {
 	struct qfq_sched *q = qdisc_priv(sch);
 	struct qfq_class *cl = (struct qfq_class *)*arg;
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 1b9d69bd6ed6..d70d470361be 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -645,7 +645,8 @@ static void sfb_unbind(struct Qdisc *sch, unsigned long arg)
 }
 
 static int sfb_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
-			    struct nlattr **tca, unsigned long *arg)
+			    struct nlattr **tca, unsigned long *arg,
+			    struct netlink_ext_ack *extack)
 {
 	return -ENOSYS;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 07/15] net: sched: sch: add extack for block callback
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (5 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 06/15] net: sched: sch: add extack to change class Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 08/15] net: sched: sch: add extack for graft callback Alexander Aring
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for block callback to prepare per-qdisc
specific changes for extack.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h | 3 ++-
 net/sched/cls_api.c       | 4 ++--
 net/sched/sch_api.c       | 2 +-
 net/sched/sch_cbq.c       | 3 ++-
 net/sched/sch_drr.c       | 3 ++-
 net/sched/sch_dsmark.c    | 3 ++-
 net/sched/sch_fq_codel.c  | 3 ++-
 net/sched/sch_hfsc.c      | 3 ++-
 net/sched/sch_htb.c       | 3 ++-
 net/sched/sch_ingress.c   | 6 ++++--
 net/sched/sch_multiq.c    | 3 ++-
 net/sched/sch_prio.c      | 3 ++-
 net/sched/sch_qfq.c       | 3 ++-
 net/sched/sch_sfb.c       | 3 ++-
 net/sched/sch_sfq.c       | 3 ++-
 15 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 219ad45cc4cd..280106691c58 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -164,7 +164,8 @@ struct Qdisc_class_ops {
 
 	/* Filter manipulation */
 	struct tcf_block *	(*tcf_block)(struct Qdisc *sch,
-					     unsigned long arg);
+					     unsigned long arg,
+					     struct netlink_ext_ack *extack);
 	unsigned long		(*bind_tcf)(struct Qdisc *, unsigned long,
 					u32 classid);
 	void			(*unbind_tcf)(struct Qdisc *, unsigned long);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5b9b8a61e8c4..446ef956a79c 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -794,7 +794,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
 	}
 
 	/* And the last stroke */
-	block = cops->tcf_block(q, cl);
+	block = cops->tcf_block(q, cl, extack);
 	if (!block) {
 		err = -EINVAL;
 		goto errout;
@@ -1041,7 +1041,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
 		if (cl == 0)
 			goto out;
 	}
-	block = cops->tcf_block(q, cl);
+	block = cops->tcf_block(q, cl, NULL);
 	if (!block)
 		goto out;
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 93171ac48443..b0604e8da876 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1761,7 +1761,7 @@ static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
 	cl = cops->find(q, portid);
 	if (!cl)
 		return;
-	block = cops->tcf_block(q, cl);
+	block = cops->tcf_block(q, cl, NULL);
 	if (!block)
 		return;
 	list_for_each_entry(chain, &block->chain_list, list) {
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 8f1832df8b4f..d46048a439a6 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1679,7 +1679,8 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg)
 	return 0;
 }
 
-static struct tcf_block *cbq_tcf_block(struct Qdisc *sch, unsigned long arg)
+static struct tcf_block *cbq_tcf_block(struct Qdisc *sch, unsigned long arg,
+				       struct netlink_ext_ack *extack)
 {
 	struct cbq_sched_data *q = qdisc_priv(sch);
 	struct cbq_class *cl = (struct cbq_class *)arg;
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 73b914bc47a4..44a2870f6f10 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -173,7 +173,8 @@ static unsigned long drr_search_class(struct Qdisc *sch, u32 classid)
 	return (unsigned long)drr_find_class(sch, classid);
 }
 
-static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl,
+				       struct netlink_ext_ack *extack)
 {
 	struct drr_sched *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 89e433bbd590..5dc5d5216fbb 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -185,7 +185,8 @@ static void dsmark_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 	}
 }
 
-static struct tcf_block *dsmark_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *dsmark_tcf_block(struct Qdisc *sch, unsigned long cl,
+					  struct netlink_ext_ack *extack)
 {
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index b4ca46aafb5a..06e5360c54d8 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -597,7 +597,8 @@ static void fq_codel_unbind(struct Qdisc *q, unsigned long cl)
 {
 }
 
-static struct tcf_block *fq_codel_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *fq_codel_tcf_block(struct Qdisc *sch, unsigned long cl,
+					    struct netlink_ext_ack *extack)
 {
 	struct fq_codel_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 11410b0e4068..961668d657a0 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1247,7 +1247,8 @@ hfsc_unbind_tcf(struct Qdisc *sch, unsigned long arg)
 	cl->filter_cnt--;
 }
 
-static struct tcf_block *hfsc_tcf_block(struct Qdisc *sch, unsigned long arg)
+static struct tcf_block *hfsc_tcf_block(struct Qdisc *sch, unsigned long arg,
+					struct netlink_ext_ack *extack)
 {
 	struct hfsc_sched *q = qdisc_priv(sch);
 	struct hfsc_class *cl = (struct hfsc_class *)arg;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index eb535a23a69b..79cf24468a38 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1525,7 +1525,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 	return err;
 }
 
-static struct tcf_block *htb_tcf_block(struct Qdisc *sch, unsigned long arg)
+static struct tcf_block *htb_tcf_block(struct Qdisc *sch, unsigned long arg,
+				       struct netlink_ext_ack *extack)
 {
 	struct htb_sched *q = qdisc_priv(sch);
 	struct htb_class *cl = (struct htb_class *)arg;
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index c703cf3a0bed..17fa8969f7e7 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -48,7 +48,8 @@ static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 {
 }
 
-static struct tcf_block *ingress_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *ingress_tcf_block(struct Qdisc *sch, unsigned long cl,
+					   struct netlink_ext_ack *extack)
 {
 	struct ingress_sched_data *q = qdisc_priv(sch);
 
@@ -153,7 +154,8 @@ static unsigned long clsact_bind_filter(struct Qdisc *sch,
 	return clsact_find(sch, classid);
 }
 
-static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl,
+					  struct netlink_ext_ack *extack)
 {
 	struct clsact_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index a8db1dbeb04f..4bcbd3636606 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -371,7 +371,8 @@ static void multiq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
 	}
 }
 
-static struct tcf_block *multiq_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *multiq_tcf_block(struct Qdisc *sch, unsigned long cl,
+					  struct netlink_ext_ack *extack)
 {
 	struct multiq_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 5f8ecbaa2610..077af4730749 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -329,7 +329,8 @@ static void prio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
 	}
 }
 
-static struct tcf_block *prio_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *prio_tcf_block(struct Qdisc *sch, unsigned long cl,
+					struct netlink_ext_ack *extack)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 1f4a84b687d2..e77e7131e620 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -565,7 +565,8 @@ static unsigned long qfq_search_class(struct Qdisc *sch, u32 classid)
 	return (unsigned long)qfq_find_class(sch, classid);
 }
 
-static struct tcf_block *qfq_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *qfq_tcf_block(struct Qdisc *sch, unsigned long cl,
+				       struct netlink_ext_ack *extack)
 {
 	struct qfq_sched *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index d70d470361be..9e01b80edfe7 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -668,7 +668,8 @@ static void sfb_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 	}
 }
 
-static struct tcf_block *sfb_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *sfb_tcf_block(struct Qdisc *sch, unsigned long cl,
+				       struct netlink_ext_ack *extack)
 {
 	struct sfb_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 3b5869c7b3f3..7a217be39f2a 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -837,7 +837,8 @@ static void sfq_unbind(struct Qdisc *q, unsigned long cl)
 {
 }
 
-static struct tcf_block *sfq_tcf_block(struct Qdisc *sch, unsigned long cl)
+static struct tcf_block *sfq_tcf_block(struct Qdisc *sch, unsigned long cl,
+				       struct netlink_ext_ack *extack)
 {
 	struct sfq_sched_data *q = qdisc_priv(sch);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 08/15] net: sched: sch: add extack for graft callback
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (6 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 07/15] net: sched: sch: add extack for block callback Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 18:38 ` [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab Alexander Aring
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for graft callback to prepare per-qdisc
specific changes for extack.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h | 3 ++-
 net/sched/sch_api.c       | 3 ++-
 net/sched/sch_cbq.c       | 2 +-
 net/sched/sch_drr.c       | 3 ++-
 net/sched/sch_dsmark.c    | 3 ++-
 net/sched/sch_hfsc.c      | 2 +-
 net/sched/sch_htb.c       | 2 +-
 net/sched/sch_mq.c        | 2 +-
 net/sched/sch_mqprio.c    | 2 +-
 net/sched/sch_multiq.c    | 2 +-
 net/sched/sch_netem.c     | 2 +-
 net/sched/sch_prio.c      | 2 +-
 net/sched/sch_qfq.c       | 3 ++-
 net/sched/sch_red.c       | 2 +-
 net/sched/sch_sfb.c       | 2 +-
 net/sched/sch_tbf.c       | 2 +-
 16 files changed, 21 insertions(+), 16 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 280106691c58..2ea04863ea34 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -150,7 +150,8 @@ struct Qdisc_class_ops {
 	/* Child qdisc manipulation */
 	struct netdev_queue *	(*select_queue)(struct Qdisc *, struct tcmsg *);
 	int			(*graft)(struct Qdisc *, unsigned long cl,
-					struct Qdisc *, struct Qdisc **);
+					struct Qdisc *, struct Qdisc **,
+					struct netlink_ext_ack *extack);
 	struct Qdisc *		(*leaf)(struct Qdisc *, unsigned long cl);
 	void			(*qlen_notify)(struct Qdisc *, unsigned long);
 
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index b0604e8da876..816e8b0c2609 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -975,7 +975,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
 			unsigned long cl = cops->find(parent, classid);
 
 			if (cl) {
-				err = cops->graft(parent, cl, new, &old);
+				err = cops->graft(parent, cl, new, &old,
+						  extack);
 			} else {
 				NL_SET_ERR_MSG(extack, "Specified class not found");
 				err = -ENOENT;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index d46048a439a6..bb7e4ccd7caf 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1371,7 +1371,7 @@ cbq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
 }
 
 static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct cbq_class *cl = (struct cbq_class *)arg;
 
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 44a2870f6f10..30e9cba54ddb 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -203,7 +203,8 @@ static void drr_unbind_tcf(struct Qdisc *sch, unsigned long arg)
 }
 
 static int drr_graft_class(struct Qdisc *sch, unsigned long arg,
-			   struct Qdisc *new, struct Qdisc **old)
+			   struct Qdisc *new, struct Qdisc **old,
+			   struct netlink_ext_ack *extack)
 {
 	struct drr_class *cl = (struct drr_class *)arg;
 
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 5dc5d5216fbb..92a36aa4c713 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -61,7 +61,8 @@ static inline int dsmark_valid_index(struct dsmark_qdisc_data *p, u16 index)
 /* ------------------------- Class/flow operations ------------------------- */
 
 static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
-			struct Qdisc *new, struct Qdisc **old)
+			struct Qdisc *new, struct Qdisc **old,
+			struct netlink_ext_ack *extack)
 {
 	struct dsmark_qdisc_data *p = qdisc_priv(sch);
 
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 961668d657a0..7f6a06ac4b9f 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1177,7 +1177,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 
 static int
 hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		 struct Qdisc **old)
+		 struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct hfsc_class *cl = (struct hfsc_class *)arg;
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 79cf24468a38..65762d57a70d 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1172,7 +1172,7 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
 }
 
 static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct htb_class *cl = (struct htb_class *)arg;
 
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index b91f7d8cb184..50292e470432 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -155,7 +155,7 @@ static struct netdev_queue *mq_select_queue(struct Qdisc *sch,
 }
 
 static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
-		    struct Qdisc **old)
+		    struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct netdev_queue *dev_queue = mq_queue_get(sch, cl);
 	struct net_device *dev = qdisc_dev(sch);
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 0379fc4ee7bb..29071cf329f3 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -320,7 +320,7 @@ static struct netdev_queue *mqprio_queue_get(struct Qdisc *sch,
 }
 
 static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
-		    struct Qdisc **old)
+			struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct net_device *dev = qdisc_dev(sch);
 	struct netdev_queue *dev_queue = mqprio_queue_get(sch, cl);
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 4bcbd3636606..177d86de4b32 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -283,7 +283,7 @@ static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
 }
 
 static int multiq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		      struct Qdisc **old)
+			struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct multiq_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index f45040b55531..7bbc13b8ca47 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -1159,7 +1159,7 @@ static int netem_dump_class(struct Qdisc *sch, unsigned long cl,
 }
 
 static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 077af4730749..8fbd65661d77 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -242,7 +242,7 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
 }
 
 static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		      struct Qdisc **old)
+		      struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct prio_sched_data *q = qdisc_priv(sch);
 	unsigned long band = arg - 1;
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index e77e7131e620..7ec893f770d2 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -595,7 +595,8 @@ static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg)
 }
 
 static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
-			   struct Qdisc *new, struct Qdisc **old)
+			   struct Qdisc *new, struct Qdisc **old,
+			   struct netlink_ext_ack *extack)
 {
 	struct qfq_class *cl = (struct qfq_class *)arg;
 
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 66b33b829b54..19616fa0a1a8 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -383,7 +383,7 @@ static int red_dump_class(struct Qdisc *sch, unsigned long cl,
 }
 
 static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 9e01b80edfe7..1a33d6c3ac42 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -617,7 +617,7 @@ static int sfb_dump_class(struct Qdisc *sch, unsigned long cl,
 }
 
 static int sfb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct sfb_sched_data *q = qdisc_priv(sch);
 
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 273228eb5ce0..db6bd23530d4 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -496,7 +496,7 @@ static int tbf_dump_class(struct Qdisc *sch, unsigned long cl,
 }
 
 static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
-		     struct Qdisc **old)
+		     struct Qdisc **old, struct netlink_ext_ack *extack)
 {
 	struct tbf_sched_data *q = qdisc_priv(sch);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (7 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 08/15] net: sched: sch: add extack for graft callback Alexander Aring
@ 2017-12-14 18:38 ` Alexander Aring
  2017-12-14 20:02   ` David Ahern
  2017-12-14 18:39 ` [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get Alexander Aring
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:38 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the function qdisc_get_rtab 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 qdisc_get_rtab failed.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/pkt_sched.h | 3 ++-
 net/sched/act_police.c  | 4 ++--
 net/sched/sch_api.c     | 9 +++++++--
 net/sched/sch_cbq.c     | 7 ++++---
 net/sched/sch_htb.c     | 6 ++++--
 net/sched/sch_tbf.c     | 6 ++++--
 6 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 240469228851..a4f21c0b4a43 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -101,7 +101,8 @@ void qdisc_hash_del(struct Qdisc *q);
 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
-					struct nlattr *tab);
+					struct nlattr *tab,
+					struct netlink_ext_ack *extack);
 void qdisc_put_rtab(struct qdisc_rate_table *tab);
 void qdisc_put_stab(struct qdisc_size_table *tab);
 void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index bf483db993a1..95d3c9097b25 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -118,13 +118,13 @@ static int tcf_act_police_init(struct net *net, struct nlattr *nla,
 	police = to_police(*a);
 	if (parm->rate.rate) {
 		err = -ENOMEM;
-		R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE]);
+		R_tab = qdisc_get_rtab(&parm->rate, tb[TCA_POLICE_RATE], NULL);
 		if (R_tab == NULL)
 			goto failure;
 
 		if (parm->peakrate.rate) {
 			P_tab = qdisc_get_rtab(&parm->peakrate,
-					       tb[TCA_POLICE_PEAKRATE]);
+					       tb[TCA_POLICE_PEAKRATE], NULL);
 			if (P_tab == NULL)
 				goto failure;
 		}
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 816e8b0c2609..24b286d763b7 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -393,13 +393,16 @@ static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab)
 static struct qdisc_rate_table *qdisc_rtab_list;
 
 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
-					struct nlattr *tab)
+					struct nlattr *tab,
+					struct netlink_ext_ack *extack)
 {
 	struct qdisc_rate_table *rtab;
 
 	if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
-	    nla_len(tab) != TC_RTAB_SIZE)
+	    nla_len(tab) != TC_RTAB_SIZE) {
+		NL_SET_ERR_MSG(extack, "Invalid rtab parameters for searching");
 		return NULL;
+	}
 
 	for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
 		if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
@@ -418,6 +421,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
 			r->linklayer = __detect_linklayer(r, rtab->data);
 		rtab->next = qdisc_rtab_list;
 		qdisc_rtab_list = rtab;
+	} else {
+		NL_SET_ERR_MSG(extack, "Failed to allocate new qdisc rtab");
 	}
 	return rtab;
 }
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index bb7e4ccd7caf..79f081eb6bb0 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1156,7 +1156,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
 
 	r = nla_data(tb[TCA_CBQ_RATE]);
 
-	q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB]);
+	q->link.R_tab = qdisc_get_rtab(r, tb[TCA_CBQ_RTAB], extack);
 	if (!q->link.R_tab)
 		return -EINVAL;
 
@@ -1484,7 +1484,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 
 		if (tb[TCA_CBQ_RATE]) {
 			rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]),
-					      tb[TCA_CBQ_RTAB]);
+					      tb[TCA_CBQ_RTAB], extack);
 			if (rtab == NULL)
 				return -EINVAL;
 		}
@@ -1537,7 +1537,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT])
 		return -EINVAL;
 
-	rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB]);
+	rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB],
+			      extack);
 	if (rtab == NULL)
 		return -EINVAL;
 
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 65762d57a70d..51be1b756e4e 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1357,10 +1357,12 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 
 	/* Keeping backward compatible with rate_table based iproute2 tc */
 	if (hopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
-		qdisc_put_rtab(qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB]));
+		qdisc_put_rtab(qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB],
+					      NULL));
 
 	if (hopt->ceil.linklayer == TC_LINKLAYER_UNAWARE)
-		qdisc_put_rtab(qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB]));
+		qdisc_put_rtab(qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB],
+					      NULL));
 
 	if (!cl) {		/* new class */
 		struct Qdisc *new_q;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index db6bd23530d4..1ab53ff80f46 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -327,11 +327,13 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 	qopt = nla_data(tb[TCA_TBF_PARMS]);
 	if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE)
 		qdisc_put_rtab(qdisc_get_rtab(&qopt->rate,
-					      tb[TCA_TBF_RTAB]));
+					      tb[TCA_TBF_RTAB],
+					      NULL));
 
 	if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE)
 			qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate,
-						      tb[TCA_TBF_PTAB]));
+						      tb[TCA_TBF_PTAB],
+						      NULL));
 
 	buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U);
 	mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (8 preceding siblings ...)
  2017-12-14 18:38 ` [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  2017-12-14 20:08   ` David Ahern
  2017-12-16 18:27   ` kbuild test robot
  2017-12-14 18:39 ` [PATCHv2 net-next 11/15] net: sch: api: add extack support in qdisc_alloc Alexander Aring
                   ` (4 subsequent siblings)
  14 siblings, 2 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

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 <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/pkt_cls.h    |  6 ++++--
 net/sched/cls_api.c      | 13 +++++++++----
 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 +-
 14 files changed, 32 insertions(+), 23 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 446ef956a79c..173107ed3726 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -282,20 +282,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, "No tcf block given");
 		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;
 	}
@@ -322,7 +326,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,
@@ -330,7 +335,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_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 17fa8969f7e7..0712fb3bcd5a 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -76,7 +76,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;
 
@@ -182,7 +182,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;
 
@@ -192,7 +193,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)
 		goto err_egress_block_get;
 
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;
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 11/15] net: sch: api: add extack support in qdisc_alloc
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (9 preceding siblings ...)
  2017-12-14 18:39 ` [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  2017-12-14 18:39 ` [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt Alexander Aring
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the function qdisc_alloc 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 qdisc_alloc failed.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/sch_generic.h | 3 ++-
 net/sched/sch_api.c       | 5 +++--
 net/sched/sch_generic.c   | 6 ++++--
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 2ea04863ea34..1dbfbec00050 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -470,7 +470,8 @@ void qdisc_destroy(struct Qdisc *qdisc);
 void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, unsigned int n,
 			       unsigned int len);
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
-			  const struct Qdisc_ops *ops);
+			  const struct Qdisc_ops *ops,
+			  struct netlink_ext_ack *extack);
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
 				const struct Qdisc_ops *ops, u32 parentid);
 void __qdisc_calculate_pkt_len(struct sk_buff *skb,
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 24b286d763b7..4c896330e2f0 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1050,10 +1050,11 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
 		goto err_out;
 	}
 
-	sch = qdisc_alloc(dev_queue, ops);
-	if (IS_ERR(sch))
+	sch = qdisc_alloc(dev_queue, ops, extack);
+	if (IS_ERR(sch)) {
 		err = PTR_ERR(sch);
 		goto err_out2;
+	}
 
 	sch->parent = parent;
 
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5cdafe88b902..01457b27d36e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -749,7 +749,8 @@ static struct lock_class_key qdisc_tx_busylock;
 static struct lock_class_key qdisc_running_key;
 
 struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
-			  const struct Qdisc_ops *ops)
+			  const struct Qdisc_ops *ops,
+			  struct netlink_ext_ack *extack)
 {
 	void *p;
 	struct Qdisc *sch;
@@ -758,6 +759,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 	struct net_device *dev;
 
 	if (!dev_queue) {
+		NL_SET_ERR_MSG(extack, "No device queue given");
 		err = -EINVAL;
 		goto errout;
 	}
@@ -829,7 +831,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
 	if (!try_module_get(ops->owner))
 		return NULL;
 
-	sch = qdisc_alloc(dev_queue, ops);
+	sch = qdisc_alloc(dev_queue, ops, NULL);
 	if (IS_ERR(sch)) {
 		module_put(ops->owner);
 		return NULL;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (10 preceding siblings ...)
  2017-12-14 18:39 ` [PATCHv2 net-next 11/15] net: sch: api: add extack support in qdisc_alloc Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  2017-12-16 19:06   ` kbuild test robot
  2017-12-14 18:39 ` [PATCHv2 net-next 13/15] net: sch: sch_cbq: add extack support Alexander Aring
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the function qdisc_create_dflt 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 qdisc_create_dflt failed. The function qdisc_create_dflt will
also call an init callback which can fail by any per-qdisc specfic handling.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 include/net/pkt_sched.h   |  3 ++-
 include/net/sch_generic.h |  3 ++-
 net/sched/sch_cbq.c       |  9 +++++----
 net/sched/sch_drr.c       |  7 ++++---
 net/sched/sch_dsmark.c    |  5 +++--
 net/sched/sch_fifo.c      |  6 ++++--
 net/sched/sch_generic.c   | 15 +++++++++------
 net/sched/sch_hfsc.c      |  8 ++++----
 net/sched/sch_htb.c       |  9 +++++----
 net/sched/sch_mq.c        |  3 ++-
 net/sched/sch_mqprio.c    |  2 +-
 net/sched/sch_multiq.c    |  2 +-
 net/sched/sch_prio.c      |  3 ++-
 net/sched/sch_qfq.c       |  8 ++++----
 net/sched/sch_red.c       |  3 ++-
 net/sched/sch_sfb.c       |  2 +-
 net/sched/sch_tbf.c       |  3 ++-
 17 files changed, 53 insertions(+), 38 deletions(-)

diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index a4f21c0b4a43..e2c75f52557b 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -89,7 +89,8 @@ extern struct Qdisc_ops pfifo_head_drop_qdisc_ops;
 
 int fifo_set_limit(struct Qdisc *q, unsigned int limit);
 struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
-			       unsigned int limit);
+			       unsigned int limit,
+			       struct netlink_ext_ack *extack);
 
 int register_qdisc(struct Qdisc_ops *qops);
 int unregister_qdisc(struct Qdisc_ops *qops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 1dbfbec00050..e4ef4f6e7baf 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -473,7 +473,8 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 			  const struct Qdisc_ops *ops,
 			  struct netlink_ext_ack *extack);
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
-				const struct Qdisc_ops *ops, u32 parentid);
+				const struct Qdisc_ops *ops, u32 parentid,
+				struct netlink_ext_ack *extack);
 void __qdisc_calculate_pkt_len(struct sk_buff *skb,
 			       const struct qdisc_size_table *stab);
 int skb_do_redirect(struct sk_buff *);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 248ea26997b9..efe5bf15b031 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1172,7 +1172,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
 	q->link.common.classid = sch->handle;
 	q->link.qdisc = sch;
 	q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-				      sch->handle);
+				      sch->handle, NULL);
 	if (!q->link.q)
 		q->link.q = &noop_qdisc;
 	else
@@ -1376,8 +1376,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 	struct cbq_class *cl = (struct cbq_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+					cl->common.classid, extack);
 		if (new == NULL)
 			return -ENOBUFS;
 	}
@@ -1596,7 +1596,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 
 	cl->R_tab = rtab;
 	rtab = NULL;
-	cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
+	cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid,
+				  NULL);
 	if (!cl->q)
 		cl->q = &noop_qdisc;
 	else
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 9dfff065e27d..bf638ce57c50 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -114,7 +114,8 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->common.classid = classid;
 	cl->quantum	   = quantum;
 	cl->qdisc	   = qdisc_create_dflt(sch->dev_queue,
-					       &pfifo_qdisc_ops, classid);
+					       &pfifo_qdisc_ops, classid,
+					       NULL);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 	else
@@ -209,8 +210,8 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg,
 	struct drr_class *cl = (struct drr_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+					cl->common.classid, NULL);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 63f523b5e282..049714c57075 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -71,7 +71,7 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
 
 	if (new == NULL) {
 		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					sch->handle);
+					sch->handle, NULL);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
@@ -381,7 +381,8 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt,
 	p->default_index = default_index;
 	p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]);
 
-	p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle);
+	p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle,
+				 NULL);
 	if (p->q == NULL)
 		p->q = &noop_qdisc;
 	else
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index c65f23c70f40..24893d3b5d22 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -166,12 +166,14 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit)
 EXPORT_SYMBOL(fifo_set_limit);
 
 struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
-			       unsigned int limit)
+			       unsigned int limit,
+			       struct netlink_ext_ack *extack)
 {
 	struct Qdisc *q;
 	int err = -ENOMEM;
 
-	q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1));
+	q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1),
+			      extack);
 	if (q) {
 		err = fifo_set_limit(q, limit);
 		if (err < 0) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 01457b27d36e..020db5e57290 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -824,21 +824,24 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 
 struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
 				const struct Qdisc_ops *ops,
-				unsigned int parentid)
+				unsigned int parentid,
+				struct netlink_ext_ack *extack)
 {
 	struct Qdisc *sch;
 
-	if (!try_module_get(ops->owner))
+	if (!try_module_get(ops->owner)) {
+		NL_SET_ERR_MSG(extack, "Failed to increase module reference counter");
 		return NULL;
+	}
 
-	sch = qdisc_alloc(dev_queue, ops, NULL);
+	sch = qdisc_alloc(dev_queue, ops, extack);
 	if (IS_ERR(sch)) {
 		module_put(ops->owner);
 		return NULL;
 	}
 	sch->parent = parentid;
 
-	if (!ops->init || ops->init(sch, NULL, NULL) == 0)
+	if (!ops->init || ops->init(sch, NULL, extack) == 0)
 		return sch;
 
 	qdisc_destroy(sch);
@@ -950,7 +953,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
 	if (dev->priv_flags & IFF_NO_QUEUE)
 		ops = &noqueue_qdisc_ops;
 
-	qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT);
+	qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL);
 	if (!qdisc) {
 		netdev_info(dev, "activation failed\n");
 		return;
@@ -973,7 +976,7 @@ static void attach_default_qdiscs(struct net_device *dev)
 		dev->qdisc = txq->qdisc_sleeping;
 		qdisc_refcount_inc(dev->qdisc);
 	} else {
-		qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
+		qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT, NULL);
 		if (qdisc) {
 			dev->qdisc = qdisc;
 			qdisc->ops->attach(qdisc);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 9ae288fcbed8..3ae9877ea205 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1062,8 +1062,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->cl_common.classid = classid;
 	cl->sched     = q;
 	cl->cl_parent = parent;
-	cl->qdisc = qdisc_create_dflt(sch->dev_queue,
-				      &pfifo_qdisc_ops, classid);
+	cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+				      classid, NULL);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 	else
@@ -1185,7 +1185,7 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 		return -EINVAL;
 	if (new == NULL) {
 		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					cl->cl_common.classid);
+					cl->cl_common.classid, NULL);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
@@ -1416,7 +1416,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
 	q->root.cl_common.classid = sch->handle;
 	q->root.sched   = q;
 	q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					  sch->handle);
+					  sch->handle, NULL);
 	if (q->root.qdisc == NULL)
 		q->root.qdisc = &noop_qdisc;
 	else
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 54e1f860f1e5..1ea9846cc6ce 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1180,7 +1180,7 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
 		return -EINVAL;
 	if (new == NULL &&
 	    (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-				     cl->common.classid)) == NULL)
+				     cl->common.classid, extack)) == NULL)
 		return -ENOBUFS;
 
 	*old = qdisc_replace(sch, new, &cl->un.leaf.q);
@@ -1290,7 +1290,8 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
 
 	if (!cl->level && htb_parent_last_child(cl)) {
 		new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					  cl->parent->common.classid);
+					  cl->parent->common.classid,
+					  NULL);
 		last_child = 1;
 	}
 
@@ -1426,8 +1427,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
 		 * so that can't be used inside of sch_tree_lock
 		 * -- thanks to Karlis Peisenieks
 		 */
-		new_q = qdisc_create_dflt(sch->dev_queue,
-					  &pfifo_qdisc_ops, classid);
+		new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+					  classid, NULL);
 		sch_tree_lock(sch);
 		if (parent && !parent->level) {
 			unsigned int qlen = parent->un.leaf.q->q.qlen;
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index 50292e470432..f062a18e9162 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -61,7 +61,8 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt,
 		dev_queue = netdev_get_tx_queue(dev, ntx);
 		qdisc = qdisc_create_dflt(dev_queue, get_default_qdisc_ops(dev, ntx),
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
-						    TC_H_MIN(ntx + 1)));
+						    TC_H_MIN(ntx + 1)),
+					  extack);
 		if (!qdisc)
 			return -ENOMEM;
 		priv->qdiscs[ntx] = qdisc;
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 29071cf329f3..0e9d761cdd80 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -230,7 +230,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
 		qdisc = qdisc_create_dflt(dev_queue,
 					  get_default_qdisc_ops(dev, i),
 					  TC_H_MAKE(TC_H_MAJ(sch->handle),
-						    TC_H_MIN(i + 1)));
+						    TC_H_MIN(i + 1)), extack);
 		if (!qdisc)
 			return -ENOMEM;
 
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 35cbaf8bd96a..1da7ea8de0ad 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -216,7 +216,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
 			child = qdisc_create_dflt(sch->dev_queue,
 						  &pfifo_qdisc_ops,
 						  TC_H_MAKE(sch->handle,
-							    i + 1));
+							    i + 1), extack);
 			if (child) {
 				sch_tree_lock(sch);
 				old = q->queues[i];
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 502352762f03..fe1510eb111f 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -176,7 +176,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt,
 	/* Before commit, make sure we can allocate all new qdiscs */
 	for (i = oldbands; i < qopt->bands; i++) {
 		queues[i] = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
-					      TC_H_MAKE(sch->handle, i + 1));
+					      TC_H_MAKE(sch->handle, i + 1),
+					      extack);
 		if (!queues[i]) {
 			while (i > oldbands)
 				qdisc_destroy(queues[--i]);
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 6ab58509cf49..bb1a9c11fc54 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -480,8 +480,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	cl->common.classid = classid;
 	cl->deficit = lmax;
 
-	cl->qdisc = qdisc_create_dflt(sch->dev_queue,
-				      &pfifo_qdisc_ops, classid);
+	cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+				      classid, NULL);
 	if (cl->qdisc == NULL)
 		cl->qdisc = &noop_qdisc;
 
@@ -601,8 +601,8 @@ static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
 	struct qfq_class *cl = (struct qfq_class *)arg;
 
 	if (new == NULL) {
-		new = qdisc_create_dflt(sch->dev_queue,
-					&pfifo_qdisc_ops, cl->common.classid);
+		new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
+					cl->common.classid, NULL);
 		if (new == NULL)
 			new = &noop_qdisc;
 	}
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 19616fa0a1a8..094fcf072e78 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -217,7 +217,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt,
 		return -EINVAL;
 
 	if (ctl->limit > 0) {
-		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit);
+		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, ctl->limit,
+					 extack);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index a1a11ded8e4f..7cbdad8419b7 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -513,7 +513,7 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
 	if (limit == 0)
 		limit = qdisc_dev(sch)->tx_queue_len;
 
-	child = fifo_create_dflt(sch, &pfifo_qdisc_ops, limit);
+	child = fifo_create_dflt(sch, &pfifo_qdisc_ops, limit, extack);
 	if (IS_ERR(child))
 		return PTR_ERR(child);
 
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 1ab53ff80f46..83e76d046993 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -386,7 +386,8 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt,
 		if (err)
 			goto done;
 	} else if (qopt->limit > 0) {
-		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit);
+		child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit,
+					 extack);
 		if (IS_ERR(child)) {
 			err = PTR_ERR(child);
 			goto done;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 13/15] net: sch: sch_cbq: add extack support
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (11 preceding siblings ...)
  2017-12-14 18:39 ` [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  2017-12-14 18:39 ` [PATCHv2 net-next 14/15] net: sch: sch_cbs: " Alexander Aring
  2017-12-14 18:39 ` [PATCHv2 net-next 15/15] net: sch: sch_drr: " Alexander Aring
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the cbq qdisc implementation by
adding NL_SET_ERR_MSG in validation of user input.
Also it serves to illustrate a use case of how the infrastructure ops
api changes are to be used by individual qdiscs.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 net/sched/sch_cbq.c | 46 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index efe5bf15b031..f42025d53cfe 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1144,15 +1144,19 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
 	hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
 	q->delay_timer.function = cbq_undelay;
 
-	if (!opt)
+	if (!opt) {
+		NL_SET_ERR_MSG(extack, "CBQ options are required for this operation");
 		return -EINVAL;
+	}
 
-	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, NULL);
+	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, extack);
 	if (err < 0)
 		return err;
 
-	if (!tb[TCA_CBQ_RTAB] || !tb[TCA_CBQ_RATE])
+	if (!tb[TCA_CBQ_RTAB] || !tb[TCA_CBQ_RATE]) {
+		NL_SET_ERR_MSG(extack, "Rate specification missing or incomplete");
 		return -EINVAL;
+	}
 
 	r = nla_data(tb[TCA_CBQ_RATE]);
 
@@ -1462,24 +1466,32 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	struct cbq_class *parent;
 	struct qdisc_rate_table *rtab = NULL;
 
-	if (!opt)
+	if (!opt) {
+		NL_SET_ERR_MSG(extack, "Mandatory qdisc options missing");
 		return -EINVAL;
+	}
 
-	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, NULL);
+	err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy, extack);
 	if (err < 0)
 		return err;
 
-	if (tb[TCA_CBQ_OVL_STRATEGY] || tb[TCA_CBQ_POLICE])
+	if (tb[TCA_CBQ_OVL_STRATEGY] || tb[TCA_CBQ_POLICE]) {
+		NL_SET_ERR_MSG(extack, "Neither overlimit strategy nor policing attributes can be used for changing class params");
 		return -EOPNOTSUPP;
+	}
 
 	if (cl) {
 		/* Check parent */
 		if (parentid) {
 			if (cl->tparent &&
-			    cl->tparent->common.classid != parentid)
+			    cl->tparent->common.classid != parentid) {
+				NL_SET_ERR_MSG(extack, "Invalid parent id");
 				return -EINVAL;
-			if (!cl->tparent && parentid != TC_H_ROOT)
+			}
+			if (!cl->tparent && parentid != TC_H_ROOT) {
+				NL_SET_ERR_MSG(extack, "Parent must be root");
 				return -EINVAL;
+			}
 		}
 
 		if (tb[TCA_CBQ_RATE]) {
@@ -1496,6 +1508,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 						    qdisc_root_sleeping_running(sch),
 						    tca[TCA_RATE]);
 			if (err) {
+				NL_SET_ERR_MSG(extack, "Failed to replace specified rate estimator");
 				qdisc_put_rtab(rtab);
 				return err;
 			}
@@ -1534,8 +1547,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (parentid == TC_H_ROOT)
 		return -EINVAL;
 
-	if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT])
+	if (!tb[TCA_CBQ_WRROPT] || !tb[TCA_CBQ_RATE] || !tb[TCA_CBQ_LSSOPT]) {
+		NL_SET_ERR_MSG(extack, "One of the following attributes MUST be specified: WRR, rate or link sharing");
 		return -EINVAL;
+	}
 
 	rtab = qdisc_get_rtab(nla_data(tb[TCA_CBQ_RATE]), tb[TCA_CBQ_RTAB],
 			      extack);
@@ -1545,8 +1560,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (classid) {
 		err = -EINVAL;
 		if (TC_H_MAJ(classid ^ sch->handle) ||
-		    cbq_class_lookup(q, classid))
+		    cbq_class_lookup(q, classid)) {
+			NL_SET_ERR_MSG(extack, "Specified class not found");
 			goto failure;
+		}
 	} else {
 		int i;
 		classid = TC_H_MAKE(sch->handle, 0x8000);
@@ -1558,8 +1575,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 				break;
 		}
 		err = -ENOSR;
-		if (i >= 0x8000)
+		if (i >= 0x8000) {
+			NL_SET_ERR_MSG(extack, "Unable to generate classid");
 			goto failure;
+		}
 		classid = classid|q->hgenerator;
 	}
 
@@ -1567,8 +1586,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 	if (parentid) {
 		parent = cbq_class_lookup(q, parentid);
 		err = -EINVAL;
-		if (!parent)
+		if (!parent) {
+			NL_SET_ERR_MSG(extack, "Failed to find parentid");
 			goto failure;
+		}
 	}
 
 	err = -ENOBUFS;
@@ -1588,6 +1609,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t
 					qdisc_root_sleeping_running(sch),
 					tca[TCA_RATE]);
 		if (err) {
+			NL_SET_ERR_MSG(extack, "Couldn't create new estimator");
 			tcf_block_put(cl->block);
 			kfree(cl);
 			goto failure;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 14/15] net: sch: sch_cbs: add extack support
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (12 preceding siblings ...)
  2017-12-14 18:39 ` [PATCHv2 net-next 13/15] net: sch: sch_cbq: add extack support Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  2017-12-14 20:11   ` David Ahern
  2017-12-14 18:39 ` [PATCHv2 net-next 15/15] net: sch: sch_drr: " Alexander Aring
  14 siblings, 1 reply; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the cbs qdisc implementation by
adding NL_SET_ERR_MSG in validation of user input.
Also it serves to illustrate a use case of how the infrastructure ops
api changes are to be used by individual qdiscs.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 net/sched/sch_cbs.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
index 8bf6e163d29c..6d09ffd2371e 100644
--- a/net/sched/sch_cbs.c
+++ b/net/sched/sch_cbs.c
@@ -219,14 +219,17 @@ static void cbs_disable_offload(struct net_device *dev,
 }
 
 static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
-			      const struct tc_cbs_qopt *opt)
+			      const struct tc_cbs_qopt *opt,
+			      struct netlink_ext_ack *extack)
 {
 	const struct net_device_ops *ops = dev->netdev_ops;
 	struct tc_cbs_qopt_offload cbs = { };
 	int err;
 
-	if (!ops->ndo_setup_tc)
+	if (!ops->ndo_setup_tc) {
+		NL_SET_ERR_MSG(extack, "Specified device does support cbs offload");
 		return -EOPNOTSUPP;
+	}
 
 	cbs.queue = q->queue;
 
@@ -237,8 +240,10 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
 	cbs.sendslope = opt->sendslope;
 
 	err = ops->ndo_setup_tc(dev, TC_SETUP_QDISC_CBS, &cbs);
-	if (err < 0)
+	if (err < 0) {
+		NL_SET_ERR_MSG(extack, "Specified device failed to setup cbs hardware offload");
 		return err;
+	}
 
 	q->enqueue = cbs_enqueue_offload;
 	q->dequeue = cbs_dequeue_offload;
@@ -255,12 +260,14 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
 	struct tc_cbs_qopt *qopt;
 	int err;
 
-	err = nla_parse_nested(tb, TCA_CBS_MAX, opt, cbs_policy, NULL);
+	err = nla_parse_nested(tb, TCA_CBS_MAX, opt, cbs_policy, extack);
 	if (err < 0)
 		return err;
 
-	if (!tb[TCA_CBS_PARMS])
+	if (!tb[TCA_CBS_PARMS]) {
+		NL_SET_ERR_MSG(extack, "Missing CBS parameter which are mandatory");
 		return -EINVAL;
+	}
 
 	qopt = nla_data(tb[TCA_CBS_PARMS]);
 
@@ -277,7 +284,7 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt,
 
 		cbs_disable_offload(dev, q);
 	} else {
-		err = cbs_enable_offload(dev, q, qopt);
+		err = cbs_enable_offload(dev, q, qopt, extack);
 		if (err < 0)
 			return err;
 	}
@@ -298,8 +305,10 @@ static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
 	struct cbs_sched_data *q = qdisc_priv(sch);
 	struct net_device *dev = qdisc_dev(sch);
 
-	if (!opt)
+	if (!opt) {
+		NL_SET_ERR_MSG(extack, "Missing CBS qdisc options  which are mandatory");
 		return -EINVAL;
+	}
 
 	q->queue = sch->dev_queue - netdev_get_tx_queue(dev, 0);
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCHv2 net-next 15/15] net: sch: sch_drr: add extack support
  2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
                   ` (13 preceding siblings ...)
  2017-12-14 18:39 ` [PATCHv2 net-next 14/15] net: sch: sch_cbs: " Alexander Aring
@ 2017-12-14 18:39 ` Alexander Aring
  14 siblings, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:39 UTC (permalink / raw)
  To: jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, Alexander Aring,
	David Ahern

This patch adds extack support for the drr qdisc implementation by
adding NL_SET_ERR_MSG in validation of user input.
Also it serves to illustrate a use case of how the infrastructure ops
api changes are to be used by individual qdiscs.

Cc: David Ahern <dsahern@gmail.com>
Signed-off-by: Alexander Aring <aring@mojatatu.com>
---
 net/sched/sch_drr.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index bf638ce57c50..e0b0cf8a9939 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -74,17 +74,21 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 	u32 quantum;
 	int err;
 
-	if (!opt)
+	if (!opt) {
+		NL_SET_ERR_MSG(extack, "DRR options are required for this operation");
 		return -EINVAL;
+	}
 
-	err = nla_parse_nested(tb, TCA_DRR_MAX, opt, drr_policy, NULL);
+	err = nla_parse_nested(tb, TCA_DRR_MAX, opt, drr_policy, extack);
 	if (err < 0)
 		return err;
 
 	if (tb[TCA_DRR_QUANTUM]) {
 		quantum = nla_get_u32(tb[TCA_DRR_QUANTUM]);
-		if (quantum == 0)
+		if (quantum == 0) {
+			NL_SET_ERR_MSG(extack, "Specified DRR quantum cannot be zero");
 			return -EINVAL;
+		}
 	} else
 		quantum = psched_mtu(qdisc_dev(sch));
 
@@ -95,8 +99,10 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 						    NULL,
 						    qdisc_root_sleeping_running(sch),
 						    tca[TCA_RATE]);
-			if (err)
+			if (err) {
+				NL_SET_ERR_MSG(extack, "Failed to replace estimator");
 				return err;
+			}
 		}
 
 		sch_tree_lock(sch);
@@ -127,6 +133,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
 					    qdisc_root_sleeping_running(sch),
 					    tca[TCA_RATE]);
 		if (err) {
+			NL_SET_ERR_MSG(extack, "Failed to replace estimator");
 			qdisc_destroy(cl->qdisc);
 			kfree(cl);
 			return err;
@@ -179,8 +186,10 @@ static struct tcf_block *drr_tcf_block(struct Qdisc *sch, unsigned long cl,
 {
 	struct drr_sched *q = qdisc_priv(sch);
 
-	if (cl)
+	if (cl) {
+		NL_SET_ERR_MSG(extack, "DRR classid must be zero");
 		return NULL;
+	}
 
 	return q->block;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors
  2017-12-14 18:38 ` [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors Alexander Aring
@ 2017-12-14 18:52   ` Alexander Aring
  2017-12-14 19:56   ` David Ahern
  1 sibling, 0 replies; 27+ messages in thread
From: Alexander Aring @ 2017-12-14 18:52 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: Cong Wang, Jiří Pírko, David Miller, netdev,
	kernel, Alexander Aring, David Ahern

Hi,

On Thu, Dec 14, 2017 at 1:38 PM, Alexander Aring <aring@mojatatu.com> wrote:
> This patch adds extack support for generic qdisc handling. The extack
> will be set deeper to each called function which is not part of netdev
> core api.
>
> Cc: David Ahern <dsahern@gmail.com>
> Signed-off-by: Alexander Aring <aring@mojatatu.com>
> ---
>  net/sched/sch_api.c | 159 ++++++++++++++++++++++++++++++++++++----------------
>  1 file changed, 112 insertions(+), 47 deletions(-)
>
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index b54917f4ad87..3ff59433781b 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -449,7 +449,8 @@ static const struct nla_policy stab_policy[TCA_STAB_MAX + 1] = {
>         [TCA_STAB_DATA] = { .type = NLA_BINARY },
>  };
>
> -static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
> +static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt,
> +                                              struct netlink_ext_ack *extack)
>  {
...
>         sch = qdisc_alloc(dev_queue, ops);
> -       if (IS_ERR(sch)) {
> +       if (IS_ERR(sch))
>                 err = PTR_ERR(sch);
>                 goto err_out2;
> -       }
>

sorry, I detect this now. brackets should still be there. Happens in
some rebase foo stuff v1, didn't contained handling of extack in this
function...

I will send v3.

- Alex

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails
  2017-12-14 18:38 ` [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails Alexander Aring
@ 2017-12-14 19:45   ` David Ahern
  0 siblings, 0 replies; 27+ messages in thread
From: David Ahern @ 2017-12-14 19:45 UTC (permalink / raw)
  To: Alexander Aring, jhs; +Cc: xiyou.wangcong, jiri, davem, netdev, kernel

On 12/14/17 11:38 AM, Alexander Aring wrote:
> This patch sets a generic netlink error message if the validation of the
> netlink attribute failed. It avoids several different settings of
> netlink messages by handle nla_parse_nested on error case.
> 
> Suggested-by: David Ahern <dsahern@gmail.com>
> Signed-off-by: Alexander Aring <aring@mojatatu.com>
> ---
>  lib/nlattr.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/lib/nlattr.c b/lib/nlattr.c
> index dfa55c873c13..a2a9506b2fb7 100644
> --- a/lib/nlattr.c
> +++ b/lib/nlattr.c
> @@ -253,8 +253,10 @@ int nla_parse(struct nlattr **tb, int maxtype, const struct nlattr *head,
>  			if (policy) {
>  				err = validate_nla(nla, maxtype, policy);
>  				if (err < 0) {
> -					if (extack)
> +					if (extack) {
> +						NL_SET_ERR_MSG(extack, "Failed to validate netlink attribute");
>  						extack->bad_attr = nla;
> +					}
>  					goto errout;
>  				}
>  			}
> 

I have a similar patch:

                        if (policy) {
                                err = validate_nla(nla, maxtype, policy);
                                if (err < 0) {
-                                       if (extack)
-                                               extack->bad_attr = nla;
+                                       NL_SET_ERR_MSG_ATTR(extack, nla,
+                                                           "Attribute
failed policy validation");
                                        goto errout;
                                }
                        }

Wording wise it notes policy validation failed but more importantly it
combines setting the error message and bad_attr into 1 macro.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors
  2017-12-14 18:38 ` [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors Alexander Aring
  2017-12-14 18:52   ` Alexander Aring
@ 2017-12-14 19:56   ` David Ahern
  1 sibling, 0 replies; 27+ messages in thread
From: David Ahern @ 2017-12-14 19:56 UTC (permalink / raw)
  To: Alexander Aring, jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, David Ahern

On 12/14/17 11:38 AM, Alexander Aring wrote:
> @@ -912,8 +920,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
>  		    (new && new->flags & TCQ_F_INGRESS)) {
>  			num_q = 1;
>  			ingress = 1;
> -			if (!dev_ingress_queue(dev))
> +			if (!dev_ingress_queue(dev)) {
> +				NL_SET_ERR_MSG(extack, "Cannot find ingress queue for specified device");

"Device does not have an ingress queue" ?


> @@ -1241,8 +1262,10 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
>  	int err;
>  
>  	if ((n->nlmsg_type != RTM_GETQDISC) &&
> -	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
> +	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
> +		NL_SET_ERR_MSG(extack, "Net admin permission required for this operation");

EPERM does not need a string.



> @@ -1309,8 +1346,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
>  	struct Qdisc *q, *p;
>  	int err;
>  
> -	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
> +	if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
> +		NL_SET_ERR_MSG(extack, "Net admin permission required for this operation");

Ditto here. Please check other patches as well.

>  		return -EPERM;
> +	}
>  
>  replay:
>  	/* Reinit, just in case something touches this. */

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab
  2017-12-14 18:38 ` [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab Alexander Aring
@ 2017-12-14 20:02   ` David Ahern
  0 siblings, 0 replies; 27+ messages in thread
From: David Ahern @ 2017-12-14 20:02 UTC (permalink / raw)
  To: Alexander Aring, jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, David Ahern

On 12/14/17 11:38 AM, Alexander Aring wrote:
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index 816e8b0c2609..24b286d763b7 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -393,13 +393,16 @@ static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab)
>  static struct qdisc_rate_table *qdisc_rtab_list;
>  
>  struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
> -					struct nlattr *tab)
> +					struct nlattr *tab,
> +					struct netlink_ext_ack *extack)
>  {
>  	struct qdisc_rate_table *rtab;
>  
>  	if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
> -	    nla_len(tab) != TC_RTAB_SIZE)
> +	    nla_len(tab) != TC_RTAB_SIZE) {
> +		NL_SET_ERR_MSG(extack, "Invalid rtab parameters for searching");

What is rtab short for? Can you expand that to something meaningful to
the user?

>  		return NULL;
> +	}
>  
>  	for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
>  		if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) &&
> @@ -418,6 +421,8 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
>  			r->linklayer = __detect_linklayer(r, rtab->data);
>  		rtab->next = qdisc_rtab_list;
>  		qdisc_rtab_list = rtab;
> +	} else {
> +		NL_SET_ERR_MSG(extack, "Failed to allocate new qdisc rtab");

ditto here

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get
  2017-12-14 18:39 ` [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get Alexander Aring
@ 2017-12-14 20:08   ` David Ahern
  2017-12-16 18:27   ` kbuild test robot
  1 sibling, 0 replies; 27+ messages in thread
From: David Ahern @ 2017-12-14 20:08 UTC (permalink / raw)
  To: Alexander Aring, jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, David Ahern

On 12/14/17 11:39 AM, Alexander Aring wrote:
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index 446ef956a79c..173107ed3726 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -282,20 +282,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, "No tcf block given");

Wrong message for the failure. !block means kzalloc 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;
>  	}

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 14/15] net: sch: sch_cbs: add extack support
  2017-12-14 18:39 ` [PATCHv2 net-next 14/15] net: sch: sch_cbs: " Alexander Aring
@ 2017-12-14 20:11   ` David Ahern
  0 siblings, 0 replies; 27+ messages in thread
From: David Ahern @ 2017-12-14 20:11 UTC (permalink / raw)
  To: Alexander Aring, jhs
  Cc: xiyou.wangcong, jiri, davem, netdev, kernel, David Ahern

On 12/14/17 11:39 AM, Alexander Aring wrote:
> diff --git a/net/sched/sch_cbs.c b/net/sched/sch_cbs.c
> index 8bf6e163d29c..6d09ffd2371e 100644
> --- a/net/sched/sch_cbs.c
> +++ b/net/sched/sch_cbs.c
> @@ -219,14 +219,17 @@ static void cbs_disable_offload(struct net_device *dev,
>  }
>  
>  static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
> -			      const struct tc_cbs_qopt *opt)
> +			      const struct tc_cbs_qopt *opt,
> +			      struct netlink_ext_ack *extack)
>  {
>  	const struct net_device_ops *ops = dev->netdev_ops;
>  	struct tc_cbs_qopt_offload cbs = { };
>  	int err;
>  
> -	if (!ops->ndo_setup_tc)
> +	if (!ops->ndo_setup_tc) {
> +		NL_SET_ERR_MSG(extack, "Specified device does support cbs offload");

does *not* support ... ?

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get
  2017-12-14 18:39 ` [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get Alexander Aring
  2017-12-14 20:08   ` David Ahern
@ 2017-12-16 18:27   ` kbuild test robot
  1 sibling, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2017-12-16 18:27 UTC (permalink / raw)
  To: Alexander Aring
  Cc: kbuild-all, jhs, xiyou.wangcong, jiri, davem, netdev, kernel,
	Alexander Aring, David Ahern

[-- Attachment #1: Type: text/plain, Size: 11773 bytes --]

Hi Alexander,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexander-Aring/net-sched-sch-introduce-extack-support/20171217-015839
config: x86_64-randconfig-x003-201751 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   net/sched/sch_atm.c: In function 'atm_tc_change':
>> net/sched/sch_atm.c:285:10: error: too few arguments to function 'tcf_block_get'
     error = tcf_block_get(&flow->block, &flow->filter_list, sch);
             ^~~~~~~~~~~~~
   In file included from net/sched/sch_atm.c:18:0:
   include/net/pkt_cls.h:41:5: note: declared here
    int tcf_block_get(struct tcf_block **p_block,
        ^~~~~~~~~~~~~
   net/sched/sch_atm.c: In function 'atm_tc_init':
   net/sched/sch_atm.c:550:8: error: too few arguments to function 'tcf_block_get'
     err = tcf_block_get(&p->link.block, &p->link.filter_list, sch);
           ^~~~~~~~~~~~~
   In file included from net/sched/sch_atm.c:18:0:
   include/net/pkt_cls.h:41:5: note: declared here
    int tcf_block_get(struct tcf_block **p_block,
        ^~~~~~~~~~~~~
   net/sched/sch_atm.c: At top level:
   net/sched/sch_atm.c:660:12: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .graft  = atm_tc_graft,
               ^~~~~~~~~~~~
   net/sched/sch_atm.c:660:12: note: (near initialization for 'atm_class_ops.graft')
   net/sched/sch_atm.c:666:15: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .tcf_block = atm_tc_tcf_block,
                  ^~~~~~~~~~~~~~~~
   net/sched/sch_atm.c:666:15: note: (near initialization for 'atm_class_ops.tcf_block')
   net/sched/sch_atm.c:680:11: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .init  = atm_tc_init,
              ^~~~~~~~~~~
   net/sched/sch_atm.c:680:11: note: (near initialization for 'atm_qdisc_ops.init')
   cc1: some warnings being treated as errors

vim +/tcf_block_get +285 net/sched/sch_atm.c

27a3421e4 Patrick McHardy   2008-01-23  192  
^1da177e4 Linus Torvalds    2005-04-16  193  static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
7eb3baddc Alexander Aring   2017-12-14  194  			 struct nlattr **tca, unsigned long *arg,
7eb3baddc Alexander Aring   2017-12-14  195  			 struct netlink_ext_ack *extack)
^1da177e4 Linus Torvalds    2005-04-16  196  {
786a90366 Stephen Hemminger 2008-01-21  197  	struct atm_qdisc_data *p = qdisc_priv(sch);
^1da177e4 Linus Torvalds    2005-04-16  198  	struct atm_flow_data *flow = (struct atm_flow_data *)*arg;
^1da177e4 Linus Torvalds    2005-04-16  199  	struct atm_flow_data *excess = NULL;
1e90474c3 Patrick McHardy   2008-01-22  200  	struct nlattr *opt = tca[TCA_OPTIONS];
1e90474c3 Patrick McHardy   2008-01-22  201  	struct nlattr *tb[TCA_ATM_MAX + 1];
^1da177e4 Linus Torvalds    2005-04-16  202  	struct socket *sock;
^1da177e4 Linus Torvalds    2005-04-16  203  	int fd, error, hdr_len;
^1da177e4 Linus Torvalds    2005-04-16  204  	void *hdr;
^1da177e4 Linus Torvalds    2005-04-16  205  
786a90366 Stephen Hemminger 2008-01-21  206  	pr_debug("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
^1da177e4 Linus Torvalds    2005-04-16  207  		"flow %p,opt %p)\n", sch, p, classid, parent, flow, opt);
^1da177e4 Linus Torvalds    2005-04-16  208  	/*
^1da177e4 Linus Torvalds    2005-04-16  209  	 * The concept of parents doesn't apply for this qdisc.
^1da177e4 Linus Torvalds    2005-04-16  210  	 */
^1da177e4 Linus Torvalds    2005-04-16  211  	if (parent && parent != TC_H_ROOT && parent != sch->handle)
^1da177e4 Linus Torvalds    2005-04-16  212  		return -EINVAL;
^1da177e4 Linus Torvalds    2005-04-16  213  	/*
^1da177e4 Linus Torvalds    2005-04-16  214  	 * ATM classes cannot be changed. In order to change properties of the
^1da177e4 Linus Torvalds    2005-04-16  215  	 * ATM connection, that socket needs to be modified directly (via the
^1da177e4 Linus Torvalds    2005-04-16  216  	 * native ATM API. In order to send a flow to a different VC, the old
^1da177e4 Linus Torvalds    2005-04-16  217  	 * class needs to be removed and a new one added. (This may be changed
^1da177e4 Linus Torvalds    2005-04-16  218  	 * later.)
^1da177e4 Linus Torvalds    2005-04-16  219  	 */
b0188d4db Patrick McHardy   2007-07-15  220  	if (flow)
b0188d4db Patrick McHardy   2007-07-15  221  		return -EBUSY;
cee63723b Patrick McHardy   2008-01-23  222  	if (opt == NULL)
^1da177e4 Linus Torvalds    2005-04-16  223  		return -EINVAL;
27a3421e4 Patrick McHardy   2008-01-23  224  
fceb6435e Johannes Berg     2017-04-12  225  	error = nla_parse_nested(tb, TCA_ATM_MAX, opt, atm_policy, NULL);
cee63723b Patrick McHardy   2008-01-23  226  	if (error < 0)
cee63723b Patrick McHardy   2008-01-23  227  		return error;
cee63723b Patrick McHardy   2008-01-23  228  
27a3421e4 Patrick McHardy   2008-01-23  229  	if (!tb[TCA_ATM_FD])
^1da177e4 Linus Torvalds    2005-04-16  230  		return -EINVAL;
1587bac49 Patrick McHardy   2008-01-23  231  	fd = nla_get_u32(tb[TCA_ATM_FD]);
786a90366 Stephen Hemminger 2008-01-21  232  	pr_debug("atm_tc_change: fd %d\n", fd);
1e90474c3 Patrick McHardy   2008-01-22  233  	if (tb[TCA_ATM_HDR]) {
1e90474c3 Patrick McHardy   2008-01-22  234  		hdr_len = nla_len(tb[TCA_ATM_HDR]);
1e90474c3 Patrick McHardy   2008-01-22  235  		hdr = nla_data(tb[TCA_ATM_HDR]);
b0188d4db Patrick McHardy   2007-07-15  236  	} else {
^1da177e4 Linus Torvalds    2005-04-16  237  		hdr_len = RFC1483LLC_LEN;
^1da177e4 Linus Torvalds    2005-04-16  238  		hdr = NULL;	/* default LLC/SNAP for IP */
^1da177e4 Linus Torvalds    2005-04-16  239  	}
1e90474c3 Patrick McHardy   2008-01-22  240  	if (!tb[TCA_ATM_EXCESS])
b0188d4db Patrick McHardy   2007-07-15  241  		excess = NULL;
^1da177e4 Linus Torvalds    2005-04-16  242  	else {
b0188d4db Patrick McHardy   2007-07-15  243  		excess = (struct atm_flow_data *)
143976ce9 WANG Cong         2017-08-24  244  			atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
b0188d4db Patrick McHardy   2007-07-15  245  		if (!excess)
b0188d4db Patrick McHardy   2007-07-15  246  			return -ENOENT;
^1da177e4 Linus Torvalds    2005-04-16  247  	}
f5e5cb755 Patrick McHardy   2008-01-23  248  	pr_debug("atm_tc_change: type %d, payload %d, hdr_len %d\n",
1e90474c3 Patrick McHardy   2008-01-22  249  		 opt->nla_type, nla_len(opt), hdr_len);
786a90366 Stephen Hemminger 2008-01-21  250  	sock = sockfd_lookup(fd, &error);
786a90366 Stephen Hemminger 2008-01-21  251  	if (!sock)
b0188d4db Patrick McHardy   2007-07-15  252  		return error;	/* f_count++ */
516e0cc56 Al Viro           2008-07-26  253  	pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file));
^1da177e4 Linus Torvalds    2005-04-16  254  	if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
^1da177e4 Linus Torvalds    2005-04-16  255  		error = -EPROTOTYPE;
^1da177e4 Linus Torvalds    2005-04-16  256  		goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  257  	}
^1da177e4 Linus Torvalds    2005-04-16  258  	/* @@@ should check if the socket is really operational or we'll crash
^1da177e4 Linus Torvalds    2005-04-16  259  	   on vcc->send */
^1da177e4 Linus Torvalds    2005-04-16  260  	if (classid) {
^1da177e4 Linus Torvalds    2005-04-16  261  		if (TC_H_MAJ(classid ^ sch->handle)) {
786a90366 Stephen Hemminger 2008-01-21  262  			pr_debug("atm_tc_change: classid mismatch\n");
^1da177e4 Linus Torvalds    2005-04-16  263  			error = -EINVAL;
^1da177e4 Linus Torvalds    2005-04-16  264  			goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  265  		}
b0188d4db Patrick McHardy   2007-07-15  266  	} else {
^1da177e4 Linus Torvalds    2005-04-16  267  		int i;
^1da177e4 Linus Torvalds    2005-04-16  268  		unsigned long cl;
^1da177e4 Linus Torvalds    2005-04-16  269  
^1da177e4 Linus Torvalds    2005-04-16  270  		for (i = 1; i < 0x8000; i++) {
^1da177e4 Linus Torvalds    2005-04-16  271  			classid = TC_H_MAKE(sch->handle, 0x8000 | i);
143976ce9 WANG Cong         2017-08-24  272  			cl = atm_tc_find(sch, classid);
786a90366 Stephen Hemminger 2008-01-21  273  			if (!cl)
b0188d4db Patrick McHardy   2007-07-15  274  				break;
^1da177e4 Linus Torvalds    2005-04-16  275  		}
^1da177e4 Linus Torvalds    2005-04-16  276  	}
786a90366 Stephen Hemminger 2008-01-21  277  	pr_debug("atm_tc_change: new id %x\n", classid);
782f79568 vignesh babu      2007-07-16  278  	flow = kzalloc(sizeof(struct atm_flow_data) + hdr_len, GFP_KERNEL);
786a90366 Stephen Hemminger 2008-01-21  279  	pr_debug("atm_tc_change: flow %p\n", flow);
^1da177e4 Linus Torvalds    2005-04-16  280  	if (!flow) {
^1da177e4 Linus Torvalds    2005-04-16  281  		error = -ENOBUFS;
^1da177e4 Linus Torvalds    2005-04-16  282  		goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  283  	}
6529eaba3 Jiri Pirko        2017-05-17  284  
69d78ef25 Jiri Pirko        2017-10-13 @285  	error = tcf_block_get(&flow->block, &flow->filter_list, sch);
6529eaba3 Jiri Pirko        2017-05-17  286  	if (error) {
6529eaba3 Jiri Pirko        2017-05-17  287  		kfree(flow);
6529eaba3 Jiri Pirko        2017-05-17  288  		goto err_out;
6529eaba3 Jiri Pirko        2017-05-17  289  	}
6529eaba3 Jiri Pirko        2017-05-17  290  
3511c9132 Changli Gao       2010-10-16  291  	flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
786a90366 Stephen Hemminger 2008-01-21  292  	if (!flow->q)
^1da177e4 Linus Torvalds    2005-04-16  293  		flow->q = &noop_qdisc;
786a90366 Stephen Hemminger 2008-01-21  294  	pr_debug("atm_tc_change: qdisc %p\n", flow->q);
^1da177e4 Linus Torvalds    2005-04-16  295  	flow->sock = sock;
^1da177e4 Linus Torvalds    2005-04-16  296  	flow->vcc = ATM_SD(sock);	/* speedup */
^1da177e4 Linus Torvalds    2005-04-16  297  	flow->vcc->user_back = flow;
786a90366 Stephen Hemminger 2008-01-21  298  	pr_debug("atm_tc_change: vcc %p\n", flow->vcc);
^1da177e4 Linus Torvalds    2005-04-16  299  	flow->old_pop = flow->vcc->pop;
^1da177e4 Linus Torvalds    2005-04-16  300  	flow->parent = p;
^1da177e4 Linus Torvalds    2005-04-16  301  	flow->vcc->pop = sch_atm_pop;
f7ebdff75 Jiri Pirko        2017-08-04  302  	flow->common.classid = classid;
^1da177e4 Linus Torvalds    2005-04-16  303  	flow->ref = 1;
^1da177e4 Linus Torvalds    2005-04-16  304  	flow->excess = excess;
6accec76f David S. Miller   2010-07-18  305  	list_add(&flow->list, &p->link.list);
^1da177e4 Linus Torvalds    2005-04-16  306  	flow->hdr_len = hdr_len;
^1da177e4 Linus Torvalds    2005-04-16  307  	if (hdr)
^1da177e4 Linus Torvalds    2005-04-16  308  		memcpy(flow->hdr, hdr, hdr_len);
^1da177e4 Linus Torvalds    2005-04-16  309  	else
^1da177e4 Linus Torvalds    2005-04-16  310  		memcpy(flow->hdr, llc_oui_ip, sizeof(llc_oui_ip));
^1da177e4 Linus Torvalds    2005-04-16  311  	*arg = (unsigned long)flow;
^1da177e4 Linus Torvalds    2005-04-16  312  	return 0;
^1da177e4 Linus Torvalds    2005-04-16  313  err_out:
^1da177e4 Linus Torvalds    2005-04-16  314  	sockfd_put(sock);
^1da177e4 Linus Torvalds    2005-04-16  315  	return error;
^1da177e4 Linus Torvalds    2005-04-16  316  }
^1da177e4 Linus Torvalds    2005-04-16  317  

:::::: The code at line 285 was first introduced by commit
:::::: 69d78ef25c7b0058674145500efb12255738ba8a net: sched: store Qdisc pointer in struct block

:::::: TO: Jiri Pirko <jiri@mellanox.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27258 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt
  2017-12-14 18:39 ` [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt Alexander Aring
@ 2017-12-16 19:06   ` kbuild test robot
  0 siblings, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2017-12-16 19:06 UTC (permalink / raw)
  To: Alexander Aring
  Cc: kbuild-all, jhs, xiyou.wangcong, jiri, davem, netdev, kernel,
	Alexander Aring, David Ahern

[-- Attachment #1: Type: text/plain, Size: 12892 bytes --]

Hi Alexander,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexander-Aring/net-sched-sch-introduce-extack-support/20171217-015839
config: x86_64-randconfig-x003-201751 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   net/sched/sch_atm.c: In function 'atm_tc_change':
   net/sched/sch_atm.c:285:10: error: too few arguments to function 'tcf_block_get'
     error = tcf_block_get(&flow->block, &flow->filter_list, sch);
             ^~~~~~~~~~~~~
   In file included from net/sched/sch_atm.c:18:0:
   include/net/pkt_cls.h:41:5: note: declared here
    int tcf_block_get(struct tcf_block **p_block,
        ^~~~~~~~~~~~~
>> net/sched/sch_atm.c:291:12: error: too few arguments to function 'qdisc_create_dflt'
     flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
               ^~~~~~~~~~~~~~~~~
   In file included from include/linux/filter.h:22:0,
                    from include/net/sock.h:64,
                    from include/linux/atmdev.h:13,
                    from net/sched/sch_atm.c:12:
   include/net/sch_generic.h:475:15: note: declared here
    struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
                  ^~~~~~~~~~~~~~~~~
   net/sched/sch_atm.c: In function 'atm_tc_init':
   net/sched/sch_atm.c:544:14: error: too few arguments to function 'qdisc_create_dflt'
     p->link.q = qdisc_create_dflt(sch->dev_queue,
                 ^~~~~~~~~~~~~~~~~
   In file included from include/linux/filter.h:22:0,
                    from include/net/sock.h:64,
                    from include/linux/atmdev.h:13,
                    from net/sched/sch_atm.c:12:
   include/net/sch_generic.h:475:15: note: declared here
    struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
                  ^~~~~~~~~~~~~~~~~
   net/sched/sch_atm.c:550:8: error: too few arguments to function 'tcf_block_get'
     err = tcf_block_get(&p->link.block, &p->link.filter_list, sch);
           ^~~~~~~~~~~~~
   In file included from net/sched/sch_atm.c:18:0:
   include/net/pkt_cls.h:41:5: note: declared here
    int tcf_block_get(struct tcf_block **p_block,
        ^~~~~~~~~~~~~
   net/sched/sch_atm.c: At top level:
   net/sched/sch_atm.c:660:12: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .graft  = atm_tc_graft,
               ^~~~~~~~~~~~
   net/sched/sch_atm.c:660:12: note: (near initialization for 'atm_class_ops.graft')
   net/sched/sch_atm.c:666:15: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .tcf_block = atm_tc_tcf_block,
                  ^~~~~~~~~~~~~~~~
   net/sched/sch_atm.c:666:15: note: (near initialization for 'atm_class_ops.tcf_block')
   net/sched/sch_atm.c:680:11: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .init  = atm_tc_init,
              ^~~~~~~~~~~
   net/sched/sch_atm.c:680:11: note: (near initialization for 'atm_qdisc_ops.init')
   cc1: some warnings being treated as errors

vim +/qdisc_create_dflt +291 net/sched/sch_atm.c

27a3421e4 Patrick McHardy   2008-01-23  192  
^1da177e4 Linus Torvalds    2005-04-16  193  static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
7eb3baddc Alexander Aring   2017-12-14  194  			 struct nlattr **tca, unsigned long *arg,
7eb3baddc Alexander Aring   2017-12-14  195  			 struct netlink_ext_ack *extack)
^1da177e4 Linus Torvalds    2005-04-16  196  {
786a90366 Stephen Hemminger 2008-01-21  197  	struct atm_qdisc_data *p = qdisc_priv(sch);
^1da177e4 Linus Torvalds    2005-04-16  198  	struct atm_flow_data *flow = (struct atm_flow_data *)*arg;
^1da177e4 Linus Torvalds    2005-04-16  199  	struct atm_flow_data *excess = NULL;
1e90474c3 Patrick McHardy   2008-01-22  200  	struct nlattr *opt = tca[TCA_OPTIONS];
1e90474c3 Patrick McHardy   2008-01-22  201  	struct nlattr *tb[TCA_ATM_MAX + 1];
^1da177e4 Linus Torvalds    2005-04-16  202  	struct socket *sock;
^1da177e4 Linus Torvalds    2005-04-16  203  	int fd, error, hdr_len;
^1da177e4 Linus Torvalds    2005-04-16  204  	void *hdr;
^1da177e4 Linus Torvalds    2005-04-16  205  
786a90366 Stephen Hemminger 2008-01-21  206  	pr_debug("atm_tc_change(sch %p,[qdisc %p],classid %x,parent %x,"
^1da177e4 Linus Torvalds    2005-04-16  207  		"flow %p,opt %p)\n", sch, p, classid, parent, flow, opt);
^1da177e4 Linus Torvalds    2005-04-16  208  	/*
^1da177e4 Linus Torvalds    2005-04-16  209  	 * The concept of parents doesn't apply for this qdisc.
^1da177e4 Linus Torvalds    2005-04-16  210  	 */
^1da177e4 Linus Torvalds    2005-04-16  211  	if (parent && parent != TC_H_ROOT && parent != sch->handle)
^1da177e4 Linus Torvalds    2005-04-16  212  		return -EINVAL;
^1da177e4 Linus Torvalds    2005-04-16  213  	/*
^1da177e4 Linus Torvalds    2005-04-16  214  	 * ATM classes cannot be changed. In order to change properties of the
^1da177e4 Linus Torvalds    2005-04-16  215  	 * ATM connection, that socket needs to be modified directly (via the
^1da177e4 Linus Torvalds    2005-04-16  216  	 * native ATM API. In order to send a flow to a different VC, the old
^1da177e4 Linus Torvalds    2005-04-16  217  	 * class needs to be removed and a new one added. (This may be changed
^1da177e4 Linus Torvalds    2005-04-16  218  	 * later.)
^1da177e4 Linus Torvalds    2005-04-16  219  	 */
b0188d4db Patrick McHardy   2007-07-15  220  	if (flow)
b0188d4db Patrick McHardy   2007-07-15  221  		return -EBUSY;
cee63723b Patrick McHardy   2008-01-23  222  	if (opt == NULL)
^1da177e4 Linus Torvalds    2005-04-16  223  		return -EINVAL;
27a3421e4 Patrick McHardy   2008-01-23  224  
fceb6435e Johannes Berg     2017-04-12  225  	error = nla_parse_nested(tb, TCA_ATM_MAX, opt, atm_policy, NULL);
cee63723b Patrick McHardy   2008-01-23  226  	if (error < 0)
cee63723b Patrick McHardy   2008-01-23  227  		return error;
cee63723b Patrick McHardy   2008-01-23  228  
27a3421e4 Patrick McHardy   2008-01-23  229  	if (!tb[TCA_ATM_FD])
^1da177e4 Linus Torvalds    2005-04-16  230  		return -EINVAL;
1587bac49 Patrick McHardy   2008-01-23  231  	fd = nla_get_u32(tb[TCA_ATM_FD]);
786a90366 Stephen Hemminger 2008-01-21  232  	pr_debug("atm_tc_change: fd %d\n", fd);
1e90474c3 Patrick McHardy   2008-01-22  233  	if (tb[TCA_ATM_HDR]) {
1e90474c3 Patrick McHardy   2008-01-22  234  		hdr_len = nla_len(tb[TCA_ATM_HDR]);
1e90474c3 Patrick McHardy   2008-01-22  235  		hdr = nla_data(tb[TCA_ATM_HDR]);
b0188d4db Patrick McHardy   2007-07-15  236  	} else {
^1da177e4 Linus Torvalds    2005-04-16  237  		hdr_len = RFC1483LLC_LEN;
^1da177e4 Linus Torvalds    2005-04-16  238  		hdr = NULL;	/* default LLC/SNAP for IP */
^1da177e4 Linus Torvalds    2005-04-16  239  	}
1e90474c3 Patrick McHardy   2008-01-22  240  	if (!tb[TCA_ATM_EXCESS])
b0188d4db Patrick McHardy   2007-07-15  241  		excess = NULL;
^1da177e4 Linus Torvalds    2005-04-16  242  	else {
b0188d4db Patrick McHardy   2007-07-15  243  		excess = (struct atm_flow_data *)
143976ce9 WANG Cong         2017-08-24  244  			atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
b0188d4db Patrick McHardy   2007-07-15  245  		if (!excess)
b0188d4db Patrick McHardy   2007-07-15  246  			return -ENOENT;
^1da177e4 Linus Torvalds    2005-04-16  247  	}
f5e5cb755 Patrick McHardy   2008-01-23  248  	pr_debug("atm_tc_change: type %d, payload %d, hdr_len %d\n",
1e90474c3 Patrick McHardy   2008-01-22  249  		 opt->nla_type, nla_len(opt), hdr_len);
786a90366 Stephen Hemminger 2008-01-21  250  	sock = sockfd_lookup(fd, &error);
786a90366 Stephen Hemminger 2008-01-21  251  	if (!sock)
b0188d4db Patrick McHardy   2007-07-15  252  		return error;	/* f_count++ */
516e0cc56 Al Viro           2008-07-26  253  	pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file));
^1da177e4 Linus Torvalds    2005-04-16  254  	if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
^1da177e4 Linus Torvalds    2005-04-16  255  		error = -EPROTOTYPE;
^1da177e4 Linus Torvalds    2005-04-16  256  		goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  257  	}
^1da177e4 Linus Torvalds    2005-04-16  258  	/* @@@ should check if the socket is really operational or we'll crash
^1da177e4 Linus Torvalds    2005-04-16  259  	   on vcc->send */
^1da177e4 Linus Torvalds    2005-04-16  260  	if (classid) {
^1da177e4 Linus Torvalds    2005-04-16  261  		if (TC_H_MAJ(classid ^ sch->handle)) {
786a90366 Stephen Hemminger 2008-01-21  262  			pr_debug("atm_tc_change: classid mismatch\n");
^1da177e4 Linus Torvalds    2005-04-16  263  			error = -EINVAL;
^1da177e4 Linus Torvalds    2005-04-16  264  			goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  265  		}
b0188d4db Patrick McHardy   2007-07-15  266  	} else {
^1da177e4 Linus Torvalds    2005-04-16  267  		int i;
^1da177e4 Linus Torvalds    2005-04-16  268  		unsigned long cl;
^1da177e4 Linus Torvalds    2005-04-16  269  
^1da177e4 Linus Torvalds    2005-04-16  270  		for (i = 1; i < 0x8000; i++) {
^1da177e4 Linus Torvalds    2005-04-16  271  			classid = TC_H_MAKE(sch->handle, 0x8000 | i);
143976ce9 WANG Cong         2017-08-24  272  			cl = atm_tc_find(sch, classid);
786a90366 Stephen Hemminger 2008-01-21  273  			if (!cl)
b0188d4db Patrick McHardy   2007-07-15  274  				break;
^1da177e4 Linus Torvalds    2005-04-16  275  		}
^1da177e4 Linus Torvalds    2005-04-16  276  	}
786a90366 Stephen Hemminger 2008-01-21  277  	pr_debug("atm_tc_change: new id %x\n", classid);
782f79568 vignesh babu      2007-07-16  278  	flow = kzalloc(sizeof(struct atm_flow_data) + hdr_len, GFP_KERNEL);
786a90366 Stephen Hemminger 2008-01-21  279  	pr_debug("atm_tc_change: flow %p\n", flow);
^1da177e4 Linus Torvalds    2005-04-16  280  	if (!flow) {
^1da177e4 Linus Torvalds    2005-04-16  281  		error = -ENOBUFS;
^1da177e4 Linus Torvalds    2005-04-16  282  		goto err_out;
^1da177e4 Linus Torvalds    2005-04-16  283  	}
6529eaba3 Jiri Pirko        2017-05-17  284  
69d78ef25 Jiri Pirko        2017-10-13 @285  	error = tcf_block_get(&flow->block, &flow->filter_list, sch);
6529eaba3 Jiri Pirko        2017-05-17  286  	if (error) {
6529eaba3 Jiri Pirko        2017-05-17  287  		kfree(flow);
6529eaba3 Jiri Pirko        2017-05-17  288  		goto err_out;
6529eaba3 Jiri Pirko        2017-05-17  289  	}
6529eaba3 Jiri Pirko        2017-05-17  290  
3511c9132 Changli Gao       2010-10-16 @291  	flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid);
786a90366 Stephen Hemminger 2008-01-21  292  	if (!flow->q)
^1da177e4 Linus Torvalds    2005-04-16  293  		flow->q = &noop_qdisc;
786a90366 Stephen Hemminger 2008-01-21  294  	pr_debug("atm_tc_change: qdisc %p\n", flow->q);
^1da177e4 Linus Torvalds    2005-04-16  295  	flow->sock = sock;
^1da177e4 Linus Torvalds    2005-04-16  296  	flow->vcc = ATM_SD(sock);	/* speedup */
^1da177e4 Linus Torvalds    2005-04-16  297  	flow->vcc->user_back = flow;
786a90366 Stephen Hemminger 2008-01-21  298  	pr_debug("atm_tc_change: vcc %p\n", flow->vcc);
^1da177e4 Linus Torvalds    2005-04-16  299  	flow->old_pop = flow->vcc->pop;
^1da177e4 Linus Torvalds    2005-04-16  300  	flow->parent = p;
^1da177e4 Linus Torvalds    2005-04-16  301  	flow->vcc->pop = sch_atm_pop;
f7ebdff75 Jiri Pirko        2017-08-04  302  	flow->common.classid = classid;
^1da177e4 Linus Torvalds    2005-04-16  303  	flow->ref = 1;
^1da177e4 Linus Torvalds    2005-04-16  304  	flow->excess = excess;
6accec76f David S. Miller   2010-07-18  305  	list_add(&flow->list, &p->link.list);
^1da177e4 Linus Torvalds    2005-04-16  306  	flow->hdr_len = hdr_len;
^1da177e4 Linus Torvalds    2005-04-16  307  	if (hdr)
^1da177e4 Linus Torvalds    2005-04-16  308  		memcpy(flow->hdr, hdr, hdr_len);
^1da177e4 Linus Torvalds    2005-04-16  309  	else
^1da177e4 Linus Torvalds    2005-04-16  310  		memcpy(flow->hdr, llc_oui_ip, sizeof(llc_oui_ip));
^1da177e4 Linus Torvalds    2005-04-16  311  	*arg = (unsigned long)flow;
^1da177e4 Linus Torvalds    2005-04-16  312  	return 0;
^1da177e4 Linus Torvalds    2005-04-16  313  err_out:
^1da177e4 Linus Torvalds    2005-04-16  314  	sockfd_put(sock);
^1da177e4 Linus Torvalds    2005-04-16  315  	return error;
^1da177e4 Linus Torvalds    2005-04-16  316  }
^1da177e4 Linus Torvalds    2005-04-16  317  

:::::: The code at line 291 was first introduced by commit
:::::: 3511c9132f8b1e1b5634e41a3331c44b0c13be70 net_sched: remove the unused parameter of qdisc_create_dflt()

:::::: TO: Changli Gao <xiaosuo@gmail.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27258 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback
  2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
@ 2017-12-16 19:08   ` kbuild test robot
  2017-12-16 19:37   ` kbuild test robot
  2017-12-16 19:55   ` kbuild test robot
  2 siblings, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2017-12-16 19:08 UTC (permalink / raw)
  To: Alexander Aring
  Cc: kbuild-all, jhs, xiyou.wangcong, jiri, davem, netdev, kernel,
	Alexander Aring, David Ahern

[-- Attachment #1: Type: text/plain, Size: 2089 bytes --]

Hi Alexander,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexander-Aring/net-sched-sch-introduce-extack-support/20171217-015839
config: i386-randconfig-a0-201750 (attached as .config)
compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All warnings (new ones prefixed by >>):

>> net//sched/sch_atm.c:679:2: warning: initialization from incompatible pointer type
     .init  = atm_tc_init,
     ^
   net//sched/sch_atm.c:679:2: warning: (near initialization for 'atm_qdisc_ops.init')

vim +679 net//sched/sch_atm.c

^1da177e4 Linus Torvalds  2005-04-16  671  
20fea08b5 Eric Dumazet    2007-11-14  672  static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
^1da177e4 Linus Torvalds  2005-04-16  673  	.cl_ops		= &atm_class_ops,
^1da177e4 Linus Torvalds  2005-04-16  674  	.id		= "atm",
^1da177e4 Linus Torvalds  2005-04-16  675  	.priv_size	= sizeof(struct atm_qdisc_data),
^1da177e4 Linus Torvalds  2005-04-16  676  	.enqueue	= atm_tc_enqueue,
^1da177e4 Linus Torvalds  2005-04-16  677  	.dequeue	= atm_tc_dequeue,
8e3af9789 Jarek Poplawski 2008-10-31  678  	.peek		= atm_tc_peek,
^1da177e4 Linus Torvalds  2005-04-16 @679  	.init		= atm_tc_init,
^1da177e4 Linus Torvalds  2005-04-16  680  	.reset		= atm_tc_reset,
^1da177e4 Linus Torvalds  2005-04-16  681  	.destroy	= atm_tc_destroy,
^1da177e4 Linus Torvalds  2005-04-16  682  	.dump		= atm_tc_dump,
^1da177e4 Linus Torvalds  2005-04-16  683  	.owner		= THIS_MODULE,
^1da177e4 Linus Torvalds  2005-04-16  684  };
^1da177e4 Linus Torvalds  2005-04-16  685  

:::::: The code at line 679 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29290 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback
  2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
  2017-12-16 19:08   ` kbuild test robot
@ 2017-12-16 19:37   ` kbuild test robot
  2017-12-16 19:55   ` kbuild test robot
  2 siblings, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2017-12-16 19:37 UTC (permalink / raw)
  To: Alexander Aring
  Cc: kbuild-all, jhs, xiyou.wangcong, jiri, davem, netdev, kernel,
	Alexander Aring, David Ahern

Hi Alexander,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexander-Aring/net-sched-sch-introduce-extack-support/20171217-015839
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)


vim +679 net/sched/sch_atm.c

^1da177e4 Linus Torvalds  2005-04-16  671  
20fea08b5 Eric Dumazet    2007-11-14  672  static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
^1da177e4 Linus Torvalds  2005-04-16  673  	.cl_ops		= &atm_class_ops,
^1da177e4 Linus Torvalds  2005-04-16  674  	.id		= "atm",
^1da177e4 Linus Torvalds  2005-04-16  675  	.priv_size	= sizeof(struct atm_qdisc_data),
^1da177e4 Linus Torvalds  2005-04-16  676  	.enqueue	= atm_tc_enqueue,
^1da177e4 Linus Torvalds  2005-04-16  677  	.dequeue	= atm_tc_dequeue,
8e3af9789 Jarek Poplawski 2008-10-31  678  	.peek		= atm_tc_peek,
^1da177e4 Linus Torvalds  2005-04-16 @679  	.init		= atm_tc_init,
^1da177e4 Linus Torvalds  2005-04-16  680  	.reset		= atm_tc_reset,
^1da177e4 Linus Torvalds  2005-04-16  681  	.destroy	= atm_tc_destroy,
^1da177e4 Linus Torvalds  2005-04-16  682  	.dump		= atm_tc_dump,
^1da177e4 Linus Torvalds  2005-04-16  683  	.owner		= THIS_MODULE,
^1da177e4 Linus Torvalds  2005-04-16  684  };
^1da177e4 Linus Torvalds  2005-04-16  685  

:::::: The code at line 679 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback
  2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
  2017-12-16 19:08   ` kbuild test robot
  2017-12-16 19:37   ` kbuild test robot
@ 2017-12-16 19:55   ` kbuild test robot
  2 siblings, 0 replies; 27+ messages in thread
From: kbuild test robot @ 2017-12-16 19:55 UTC (permalink / raw)
  To: Alexander Aring
  Cc: kbuild-all, jhs, xiyou.wangcong, jiri, davem, netdev, kernel,
	Alexander Aring, David Ahern

[-- Attachment #1: Type: text/plain, Size: 2194 bytes --]

Hi Alexander,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexander-Aring/net-sched-sch-introduce-extack-support/20171217-015839
config: x86_64-randconfig-x003-201751 (attached as .config)
compiler: gcc-7 (Debian 7.2.0-12) 7.2.1 20171025
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

>> net//sched/sch_atm.c:679:11: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
     .init  = atm_tc_init,
              ^~~~~~~~~~~
   net//sched/sch_atm.c:679:11: note: (near initialization for 'atm_qdisc_ops.init')
   cc1: some warnings being treated as errors

vim +679 net//sched/sch_atm.c

^1da177e4 Linus Torvalds  2005-04-16  671  
20fea08b5 Eric Dumazet    2007-11-14  672  static struct Qdisc_ops atm_qdisc_ops __read_mostly = {
^1da177e4 Linus Torvalds  2005-04-16  673  	.cl_ops		= &atm_class_ops,
^1da177e4 Linus Torvalds  2005-04-16  674  	.id		= "atm",
^1da177e4 Linus Torvalds  2005-04-16  675  	.priv_size	= sizeof(struct atm_qdisc_data),
^1da177e4 Linus Torvalds  2005-04-16  676  	.enqueue	= atm_tc_enqueue,
^1da177e4 Linus Torvalds  2005-04-16  677  	.dequeue	= atm_tc_dequeue,
8e3af9789 Jarek Poplawski 2008-10-31  678  	.peek		= atm_tc_peek,
^1da177e4 Linus Torvalds  2005-04-16 @679  	.init		= atm_tc_init,
^1da177e4 Linus Torvalds  2005-04-16  680  	.reset		= atm_tc_reset,
^1da177e4 Linus Torvalds  2005-04-16  681  	.destroy	= atm_tc_destroy,
^1da177e4 Linus Torvalds  2005-04-16  682  	.dump		= atm_tc_dump,
^1da177e4 Linus Torvalds  2005-04-16  683  	.owner		= THIS_MODULE,
^1da177e4 Linus Torvalds  2005-04-16  684  };
^1da177e4 Linus Torvalds  2005-04-16  685  

:::::: The code at line 679 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27258 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2017-12-16 19:56 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-14 18:38 [PATCHv2 net-next 00/15] net: sched: sch: introduce extack support Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 01/15] net: sched: fix coding style issues Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 02/15] lib: nlattr: set extack msg if validate_nla fails Alexander Aring
2017-12-14 19:45   ` David Ahern
2017-12-14 18:38 ` [PATCHv2 net-next 03/15] net: sched: sch_api: handle generic qdisc errors Alexander Aring
2017-12-14 18:52   ` Alexander Aring
2017-12-14 19:56   ` David Ahern
2017-12-14 18:38 ` [PATCHv2 net-next 04/15] net: sched: sch: add extack for init callback Alexander Aring
2017-12-16 19:08   ` kbuild test robot
2017-12-16 19:37   ` kbuild test robot
2017-12-16 19:55   ` kbuild test robot
2017-12-14 18:38 ` [PATCHv2 net-next 05/15] net: sched: sch: add extack for change qdisc ops Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 06/15] net: sched: sch: add extack to change class Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 07/15] net: sched: sch: add extack for block callback Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 08/15] net: sched: sch: add extack for graft callback Alexander Aring
2017-12-14 18:38 ` [PATCHv2 net-next 09/15] net: sch: api: add extack support in qdisc_get_rtab Alexander Aring
2017-12-14 20:02   ` David Ahern
2017-12-14 18:39 ` [PATCHv2 net-next 10/15] net: sch: api: add extack support in tcf_block_get Alexander Aring
2017-12-14 20:08   ` David Ahern
2017-12-16 18:27   ` kbuild test robot
2017-12-14 18:39 ` [PATCHv2 net-next 11/15] net: sch: api: add extack support in qdisc_alloc Alexander Aring
2017-12-14 18:39 ` [PATCHv2 net-next 12/15] net: sch: api: add extack support in qdisc_create_dflt Alexander Aring
2017-12-16 19:06   ` kbuild test robot
2017-12-14 18:39 ` [PATCHv2 net-next 13/15] net: sch: sch_cbq: add extack support Alexander Aring
2017-12-14 18:39 ` [PATCHv2 net-next 14/15] net: sch: sch_cbs: " Alexander Aring
2017-12-14 20:11   ` David Ahern
2017-12-14 18:39 ` [PATCHv2 net-next 15/15] net: sch: sch_drr: " Alexander Aring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.