flow_dissector: Pull locking up from prog attach callback
Split out the part of attach callback that happens with attach/detach lock acquired. This structures the prog attach callback in a way that opens up doors for moving the locking out of flow_dissector and into generic callbacks for attaching/detaching progs to netns in subsequent patches. Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/bpf/20200531082846.2117903-2-jakub@cloudflare.com
This commit is contained in:
parent
febeb6dff7
commit
171526f6fe
|
@ -109,15 +109,10 @@ int skb_flow_dissector_prog_query(const union bpf_attr *attr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
|
||||
struct bpf_prog *prog)
|
||||
static int flow_dissector_bpf_prog_attach(struct net *net,
|
||||
struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_prog *attached;
|
||||
struct net *net;
|
||||
int ret = 0;
|
||||
|
||||
net = current->nsproxy->net_ns;
|
||||
mutex_lock(&flow_dissector_mutex);
|
||||
|
||||
if (net == &init_net) {
|
||||
/* BPF flow dissector in the root namespace overrides
|
||||
|
@ -130,33 +125,38 @@ int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
|
|||
for_each_net(ns) {
|
||||
if (ns == &init_net)
|
||||
continue;
|
||||
if (rcu_access_pointer(ns->flow_dissector_prog)) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
if (rcu_access_pointer(ns->flow_dissector_prog))
|
||||
return -EEXIST;
|
||||
}
|
||||
} else {
|
||||
/* Make sure root flow dissector is not attached
|
||||
* when attaching to the non-root namespace.
|
||||
*/
|
||||
if (rcu_access_pointer(init_net.flow_dissector_prog)) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
if (rcu_access_pointer(init_net.flow_dissector_prog))
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
attached = rcu_dereference_protected(net->flow_dissector_prog,
|
||||
lockdep_is_held(&flow_dissector_mutex));
|
||||
if (attached == prog) {
|
||||
if (attached == prog)
|
||||
/* The same program cannot be attached twice */
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
return -EINVAL;
|
||||
|
||||
rcu_assign_pointer(net->flow_dissector_prog, prog);
|
||||
if (attached)
|
||||
bpf_prog_put(attached);
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
|
||||
struct bpf_prog *prog)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&flow_dissector_mutex);
|
||||
ret = flow_dissector_bpf_prog_attach(current->nsproxy->net_ns, prog);
|
||||
mutex_unlock(&flow_dissector_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user