Commit 715df5ec authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

net: sched: propagate extack to cls->destroy callbacks

Propagate extack to cls->destroy callbacks when called from
non-error paths.  On error paths pass NULL to avoid overwriting
the failure message.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 46410c2e
...@@ -233,7 +233,8 @@ struct tcf_proto_ops { ...@@ -233,7 +233,8 @@ struct tcf_proto_ops {
const struct tcf_proto *, const struct tcf_proto *,
struct tcf_result *); struct tcf_result *);
int (*init)(struct tcf_proto*); int (*init)(struct tcf_proto*);
void (*destroy)(struct tcf_proto*); void (*destroy)(struct tcf_proto *tp,
struct netlink_ext_ack *extack);
void* (*get)(struct tcf_proto*, u32 handle); void* (*get)(struct tcf_proto*, u32 handle);
int (*change)(struct net *net, struct sk_buff *, int (*change)(struct net *net, struct sk_buff *,
......
...@@ -172,9 +172,10 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol, ...@@ -172,9 +172,10 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
return ERR_PTR(err); return ERR_PTR(err);
} }
static void tcf_proto_destroy(struct tcf_proto *tp) static void tcf_proto_destroy(struct tcf_proto *tp,
struct netlink_ext_ack *extack)
{ {
tp->ops->destroy(tp); tp->ops->destroy(tp, extack);
module_put(tp->ops->owner); module_put(tp->ops->owner);
kfree_rcu(tp, rcu); kfree_rcu(tp, rcu);
} }
...@@ -223,7 +224,7 @@ static void tcf_chain_flush(struct tcf_chain *chain) ...@@ -223,7 +224,7 @@ static void tcf_chain_flush(struct tcf_chain *chain)
tcf_chain_head_change(chain, NULL); tcf_chain_head_change(chain, NULL);
while (tp) { while (tp) {
RCU_INIT_POINTER(chain->filter_chain, tp->next); RCU_INIT_POINTER(chain->filter_chain, tp->next);
tcf_proto_destroy(tp); tcf_proto_destroy(tp, NULL);
tp = rtnl_dereference(chain->filter_chain); tp = rtnl_dereference(chain->filter_chain);
tcf_chain_put(chain); tcf_chain_put(chain);
} }
...@@ -1182,7 +1183,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -1182,7 +1183,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
tcf_chain_tp_remove(chain, &chain_info, tp); tcf_chain_tp_remove(chain, &chain_info, tp);
tfilter_notify(net, skb, n, tp, block, q, parent, fh, tfilter_notify(net, skb, n, tp, block, q, parent, fh,
RTM_DELTFILTER, false); RTM_DELTFILTER, false);
tcf_proto_destroy(tp); tcf_proto_destroy(tp, extack);
err = 0; err = 0;
goto errout; goto errout;
} }
...@@ -1200,7 +1201,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -1200,7 +1201,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
case RTM_NEWTFILTER: case RTM_NEWTFILTER:
if (n->nlmsg_flags & NLM_F_EXCL) { if (n->nlmsg_flags & NLM_F_EXCL) {
if (tp_created) if (tp_created)
tcf_proto_destroy(tp); tcf_proto_destroy(tp, NULL);
NL_SET_ERR_MSG(extack, "Filter already exists"); NL_SET_ERR_MSG(extack, "Filter already exists");
err = -EEXIST; err = -EEXIST;
goto errout; goto errout;
...@@ -1214,7 +1215,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -1214,7 +1215,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
goto errout; goto errout;
if (last) { if (last) {
tcf_chain_tp_remove(chain, &chain_info, tp); tcf_chain_tp_remove(chain, &chain_info, tp);
tcf_proto_destroy(tp); tcf_proto_destroy(tp, extack);
} }
goto errout; goto errout;
case RTM_GETTFILTER: case RTM_GETTFILTER:
...@@ -1240,7 +1241,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, ...@@ -1240,7 +1241,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
RTM_NEWTFILTER, false); RTM_NEWTFILTER, false);
} else { } else {
if (tp_created) if (tp_created)
tcf_proto_destroy(tp); tcf_proto_destroy(tp, NULL);
} }
errout: errout:
......
...@@ -112,7 +112,7 @@ static void basic_delete_filter(struct rcu_head *head) ...@@ -112,7 +112,7 @@ static void basic_delete_filter(struct rcu_head *head)
tcf_queue_work(&f->work); tcf_queue_work(&f->work);
} }
static void basic_destroy(struct tcf_proto *tp) static void basic_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct basic_head *head = rtnl_dereference(tp->root); struct basic_head *head = rtnl_dereference(tp->root);
struct basic_filter *f, *n; struct basic_filter *f, *n;
......
...@@ -314,7 +314,8 @@ static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last, ...@@ -314,7 +314,8 @@ static int cls_bpf_delete(struct tcf_proto *tp, void *arg, bool *last,
return 0; return 0;
} }
static void cls_bpf_destroy(struct tcf_proto *tp) static void cls_bpf_destroy(struct tcf_proto *tp,
struct netlink_ext_ack *extack)
{ {
struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_head *head = rtnl_dereference(tp->root);
struct cls_bpf_prog *prog, *tmp; struct cls_bpf_prog *prog, *tmp;
......
...@@ -143,7 +143,8 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, ...@@ -143,7 +143,8 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
return err; return err;
} }
static void cls_cgroup_destroy(struct tcf_proto *tp) static void cls_cgroup_destroy(struct tcf_proto *tp,
struct netlink_ext_ack *extack)
{ {
struct cls_cgroup_head *head = rtnl_dereference(tp->root); struct cls_cgroup_head *head = rtnl_dereference(tp->root);
......
...@@ -600,7 +600,7 @@ static int flow_init(struct tcf_proto *tp) ...@@ -600,7 +600,7 @@ static int flow_init(struct tcf_proto *tp)
return 0; return 0;
} }
static void flow_destroy(struct tcf_proto *tp) static void flow_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct flow_head *head = rtnl_dereference(tp->root); struct flow_head *head = rtnl_dereference(tp->root);
struct flow_filter *f, *next; struct flow_filter *f, *next;
......
...@@ -315,7 +315,7 @@ static void fl_destroy_rcu(struct rcu_head *rcu) ...@@ -315,7 +315,7 @@ static void fl_destroy_rcu(struct rcu_head *rcu)
schedule_work(&head->work); schedule_work(&head->work);
} }
static void fl_destroy(struct tcf_proto *tp) static void fl_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct cls_fl_head *head = rtnl_dereference(tp->root); struct cls_fl_head *head = rtnl_dereference(tp->root);
struct cls_fl_filter *f, *next; struct cls_fl_filter *f, *next;
......
...@@ -149,7 +149,7 @@ static void fw_delete_filter(struct rcu_head *head) ...@@ -149,7 +149,7 @@ static void fw_delete_filter(struct rcu_head *head)
tcf_queue_work(&f->work); tcf_queue_work(&f->work);
} }
static void fw_destroy(struct tcf_proto *tp) static void fw_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct fw_head *head = rtnl_dereference(tp->root); struct fw_head *head = rtnl_dereference(tp->root);
struct fw_filter *f; struct fw_filter *f;
......
...@@ -114,7 +114,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp, ...@@ -114,7 +114,7 @@ static int mall_replace_hw_filter(struct tcf_proto *tp,
return 0; return 0;
} }
static void mall_destroy(struct tcf_proto *tp) static void mall_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct cls_mall_head *head = rtnl_dereference(tp->root); struct cls_mall_head *head = rtnl_dereference(tp->root);
......
...@@ -281,7 +281,7 @@ static void route4_delete_filter(struct rcu_head *head) ...@@ -281,7 +281,7 @@ static void route4_delete_filter(struct rcu_head *head)
tcf_queue_work(&f->work); tcf_queue_work(&f->work);
} }
static void route4_destroy(struct tcf_proto *tp) static void route4_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct route4_head *head = rtnl_dereference(tp->root); struct route4_head *head = rtnl_dereference(tp->root);
int h1, h2; int h1, h2;
......
...@@ -322,7 +322,7 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f) ...@@ -322,7 +322,7 @@ static void rsvp_delete_filter(struct tcf_proto *tp, struct rsvp_filter *f)
__rsvp_delete_filter(f); __rsvp_delete_filter(f);
} }
static void rsvp_destroy(struct tcf_proto *tp) static void rsvp_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct rsvp_head *data = rtnl_dereference(tp->root); struct rsvp_head *data = rtnl_dereference(tp->root);
int h1, h2; int h1, h2;
......
...@@ -581,7 +581,8 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) ...@@ -581,7 +581,8 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker)
} }
} }
static void tcindex_destroy(struct tcf_proto *tp) static void tcindex_destroy(struct tcf_proto *tp,
struct netlink_ext_ack *extack)
{ {
struct tcindex_data *p = rtnl_dereference(tp->root); struct tcindex_data *p = rtnl_dereference(tp->root);
struct tcf_walker walker; struct tcf_walker walker;
......
...@@ -638,7 +638,7 @@ static bool ht_empty(struct tc_u_hnode *ht) ...@@ -638,7 +638,7 @@ static bool ht_empty(struct tc_u_hnode *ht)
return true; return true;
} }
static void u32_destroy(struct tcf_proto *tp) static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
{ {
struct tc_u_common *tp_c = tp->data; struct tc_u_common *tp_c = tp->data;
struct tc_u_hnode *root_ht = rtnl_dereference(tp->root); struct tc_u_hnode *root_ht = rtnl_dereference(tp->root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment