mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
net/sched: fix filter flushing
When user instructs to remove all filters from chain, we cannot destroy
the chain as other actions may hold a reference. Also the put in errout
would try to destroy it again. So instead, just walk the chain and remove
all existing filters.
Fixes: 5bc1701881
("net: sched: introduce multichain support for filters")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
31efcc250a
commit
f93e1cdcf4
@ -201,15 +201,22 @@ static struct tcf_chain *tcf_chain_create(struct tcf_block *block,
|
||||
return chain;
|
||||
}
|
||||
|
||||
static void tcf_chain_destroy(struct tcf_chain *chain)
|
||||
static void tcf_chain_flush(struct tcf_chain *chain)
|
||||
{
|
||||
struct tcf_proto *tp;
|
||||
|
||||
list_del(&chain->list);
|
||||
if (*chain->p_filter_chain)
|
||||
RCU_INIT_POINTER(*chain->p_filter_chain, NULL);
|
||||
while ((tp = rtnl_dereference(chain->filter_chain)) != NULL) {
|
||||
RCU_INIT_POINTER(chain->filter_chain, tp->next);
|
||||
tcf_proto_destroy(tp);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcf_chain_destroy(struct tcf_chain *chain)
|
||||
{
|
||||
list_del(&chain->list);
|
||||
tcf_chain_flush(chain);
|
||||
kfree(chain);
|
||||
}
|
||||
|
||||
@ -510,7 +517,7 @@ replay:
|
||||
|
||||
if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) {
|
||||
tfilter_notify_chain(net, skb, n, chain, RTM_DELTFILTER);
|
||||
tcf_chain_destroy(chain);
|
||||
tcf_chain_flush(chain);
|
||||
err = 0;
|
||||
goto errout;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user