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: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Simon Horman <simon.horman@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
46410c2efa
Коммит
715df5ecab
|
@ -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 @@ errout:
|
||||||
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)
|
||||||
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 @@ replay:
|
||||||
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 @@ replay:
|
||||||
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 @@ replay:
|
||||||
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 @@ replay:
|
||||||
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)
|
||||||
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,
|
||||||
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 @@ errout:
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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)
|
||||||
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)
|
||||||
__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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче