|
@@ -143,11 +143,12 @@ static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
|
|
|
.index = prog->tcf_index,
|
|
|
.refcnt = refcount_read(&prog->tcf_refcnt) - ref,
|
|
|
.bindcnt = atomic_read(&prog->tcf_bindcnt) - bind,
|
|
|
- .action = prog->tcf_action,
|
|
|
};
|
|
|
struct tcf_t tm;
|
|
|
int ret;
|
|
|
|
|
|
+ spin_lock(&prog->tcf_lock);
|
|
|
+ opt.action = prog->tcf_action;
|
|
|
if (nla_put(skb, TCA_ACT_BPF_PARMS, sizeof(opt), &opt))
|
|
|
goto nla_put_failure;
|
|
|
|
|
@@ -163,9 +164,11 @@ static int tcf_bpf_dump(struct sk_buff *skb, struct tc_action *act,
|
|
|
TCA_ACT_BPF_PAD))
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
+ spin_unlock(&prog->tcf_lock);
|
|
|
return skb->len;
|
|
|
|
|
|
nla_put_failure:
|
|
|
+ spin_unlock(&prog->tcf_lock);
|
|
|
nlmsg_trim(skb, tp);
|
|
|
return -1;
|
|
|
}
|
|
@@ -264,7 +267,7 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,
|
|
|
{
|
|
|
cfg->is_ebpf = tcf_bpf_is_ebpf(prog);
|
|
|
/* updates to prog->filter are prevented, since it's called either
|
|
|
- * with rtnl lock or during final cleanup in rcu callback
|
|
|
+ * with tcf lock or during final cleanup in rcu callback
|
|
|
*/
|
|
|
cfg->filter = rcu_dereference_protected(prog->filter, 1);
|
|
|
|
|
@@ -336,8 +339,8 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
|
|
|
goto out;
|
|
|
|
|
|
prog = to_bpf(*act);
|
|
|
- ASSERT_RTNL();
|
|
|
|
|
|
+ spin_lock(&prog->tcf_lock);
|
|
|
if (res != ACT_P_CREATED)
|
|
|
tcf_bpf_prog_fill_cfg(prog, &old);
|
|
|
|
|
@@ -349,6 +352,7 @@ static int tcf_bpf_init(struct net *net, struct nlattr *nla,
|
|
|
|
|
|
prog->tcf_action = parm->action;
|
|
|
rcu_assign_pointer(prog->filter, cfg.filter);
|
|
|
+ spin_unlock(&prog->tcf_lock);
|
|
|
|
|
|
if (res == ACT_P_CREATED) {
|
|
|
tcf_idr_insert(tn, *act);
|