Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90bbec0f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-sched-extack'



Alexander Aring says:

====================
net: sched: sch: introduce extack support

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 Ahern which gave me some
hints how to deal with extack support.

Cc: David Ahern <dsahern@gmail.com>

changes since v4:
 - rebase on current net-next/master
 - fix several typos (also David Ahren to Ahern, I am sorry)
 - Add acked by Jamal

changes since v3:
 - remove patch 2/2 lib: nlattr: set extack msg if validate_nla fails since
   David Ahern has a better solution
 - Remove check on net admin permission since -EPERM indicates it already
 - Change rtab to "rate table" - this is what it's stands for
 - Fix cbs *not* support messages
 - Fix tcf block error message for allocation, allocation will be still there
   because there are multiple places which returns -ENOMEM
 - Finnally also took care about sch_atm, sorry somehow I forgot this one and
   I hope I didn't forgot any sch implementation to add new callback parameters

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
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8f36e000 a7c31693
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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);
+4 −2
Original line number Diff line number Diff line
@@ -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);
@@ -101,7 +102,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);
+14 −7
Original line number Diff line number Diff line
@@ -151,20 +151,23 @@ 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);

	/* 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);

	/* 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);
@@ -189,11 +192,13 @@ 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,
					  struct nlattr *arg);
					  struct nlattr *arg,
					  struct netlink_ext_ack *extack);
	void			(*attach)(struct Qdisc *sch);

	int			(*dump)(struct Qdisc *, struct sk_buff *);
@@ -466,9 +471,11 @@ 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);
				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 *);
+2 −2
Original line number Diff line number Diff line
@@ -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;
		}
+11 −6
Original line number Diff line number Diff line
@@ -281,20 +281,24 @@ static void tcf_block_offload_unbind(struct tcf_block *block, struct Qdisc *q,
}

int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
		      struct tcf_block_ext_info *ei)
		      struct tcf_block_ext_info *ei,
		      struct netlink_ext_ack *extack)
{
	struct tcf_block *block = kzalloc(sizeof(*block), GFP_KERNEL);
	struct tcf_chain *chain;
	int err;

	if (!block)
	if (!block) {
		NL_SET_ERR_MSG(extack, "Memory allocation for block failed");
		return -ENOMEM;
	}
	INIT_LIST_HEAD(&block->chain_list);
	INIT_LIST_HEAD(&block->cb_list);

	/* Create chain 0 by default, it has to be always present. */
	chain = tcf_chain_create(block, 0);
	if (!chain) {
		NL_SET_ERR_MSG(extack, "Failed to create new tcf chain");
		err = -ENOMEM;
		goto err_chain_create;
	}
@@ -321,7 +325,8 @@ static void tcf_chain_head_change_dflt(struct tcf_proto *tp_head, void *priv)
}

int tcf_block_get(struct tcf_block **p_block,
		  struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q)
		  struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
		  struct netlink_ext_ack *extack)
{
	struct tcf_block_ext_info ei = {
		.chain_head_change = tcf_chain_head_change_dflt,
@@ -329,7 +334,7 @@ int tcf_block_get(struct tcf_block **p_block,
	};

	WARN_ON(!p_filter_chain);
	return tcf_block_get_ext(p_block, q, &ei);
	return tcf_block_get_ext(p_block, q, &ei, extack);
}
EXPORT_SYMBOL(tcf_block_get);

@@ -793,7 +798,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;
@@ -1040,7 +1045,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;

Loading