Commit aecc5cef authored by Jamal Hadi Salim's avatar Jamal Hadi Salim Committed by David S. Miller

net sched actions: fix GETing actions

With the batch changes that translated transient actions into
a temporary list lost in the translation was the fact that
tcf_action_destroy() will eventually delete the action from
the permanent location if the refcount is zero.

Example of what broke:
...add a gact action to drop
sudo $TC actions add action drop index 10
...now retrieve it, looks good
sudo $TC actions get action gact index 10
...retrieve it again and find it is gone!
sudo $TC actions get action gact index 10

Fixes: 22dc13c8 ("net_sched: convert tcf_exts from list to pointer array"),
Fixes: 824a7e88 ("net_sched: remove an unnecessary list_del()")
Fixes: f07fed82 ("net_sched: remove the leftover cleanup_a()")
Acked-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1d9423ae
...@@ -592,6 +592,17 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, ...@@ -592,6 +592,17 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
return ERR_PTR(err); return ERR_PTR(err);
} }
static void cleanup_a(struct list_head *actions, int ovr)
{
struct tc_action *a;
if (!ovr)
return;
list_for_each_entry(a, actions, list)
a->tcfa_refcnt--;
}
int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est, int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est,
char *name, int ovr, int bind, struct list_head *actions) char *name, int ovr, int bind, struct list_head *actions)
{ {
...@@ -611,8 +622,15 @@ int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est, ...@@ -611,8 +622,15 @@ int tcf_action_init(struct net *net, struct nlattr *nla, struct nlattr *est,
goto err; goto err;
} }
act->order = i; act->order = i;
if (ovr)
act->tcfa_refcnt++;
list_add_tail(&act->list, actions); list_add_tail(&act->list, actions);
} }
/* Remove the temp refcnt which was necessary to protect against
* destroying an existing action which was being replaced
*/
cleanup_a(actions, ovr);
return 0; return 0;
err: err:
...@@ -882,6 +900,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, ...@@ -882,6 +900,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
goto err; goto err;
} }
act->order = i; act->order = i;
if (event == RTM_GETACTION)
act->tcfa_refcnt++;
list_add_tail(&act->list, &actions); list_add_tail(&act->list, &actions);
} }
......
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