Skip to content

Commit b27f7bb

Browse files
jsitnickiAlexei Starovoitov
authored andcommitted
flow_dissector: Move out netns_bpf prog callbacks
Move functions to manage BPF programs attached to netns that are not specific to flow dissector to a dedicated module named bpf/net_namespace.c. The set of functions will grow with the addition of bpf_link support for netns attached programs. This patch prepares ground by creating a place for it. This is a code move with no functional changes intended. Signed-off-by: Jakub Sitnicki <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent a3fd7ce commit b27f7bb

File tree

4 files changed

+144
-121
lines changed

4 files changed

+144
-121
lines changed

include/net/flow_dissector.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <linux/string.h>
99
#include <uapi/linux/if_ether.h>
1010

11+
struct bpf_prog;
12+
struct net;
1113
struct sk_buff;
1214

1315
/**
@@ -369,4 +371,8 @@ flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
369371
memset(key_basic, 0, sizeof(*key_basic));
370372
}
371373

374+
#ifdef CONFIG_BPF_SYSCALL
375+
int flow_dissector_bpf_prog_attach(struct net *net, struct bpf_prog *prog);
376+
#endif /* CONFIG_BPF_SYSCALL */
377+
372378
#endif

kernel/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_NET),y)
1313
obj-$(CONFIG_BPF_SYSCALL) += devmap.o
1414
obj-$(CONFIG_BPF_SYSCALL) += cpumap.o
1515
obj-$(CONFIG_BPF_SYSCALL) += offload.o
16+
obj-$(CONFIG_BPF_SYSCALL) += net_namespace.o
1617
endif
1718
ifeq ($(CONFIG_PERF_EVENTS),y)
1819
obj-$(CONFIG_BPF_SYSCALL) += stackmap.o

kernel/bpf/net_namespace.c

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <linux/bpf.h>
4+
#include <linux/filter.h>
5+
#include <net/net_namespace.h>
6+
7+
/*
8+
* Functions to manage BPF programs attached to netns
9+
*/
10+
11+
/* Protects updates to netns_bpf */
12+
DEFINE_MUTEX(netns_bpf_mutex);
13+
14+
int netns_bpf_prog_query(const union bpf_attr *attr,
15+
union bpf_attr __user *uattr)
16+
{
17+
__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
18+
u32 prog_id, prog_cnt = 0, flags = 0;
19+
enum netns_bpf_attach_type type;
20+
struct bpf_prog *attached;
21+
struct net *net;
22+
23+
if (attr->query.query_flags)
24+
return -EINVAL;
25+
26+
type = to_netns_bpf_attach_type(attr->query.attach_type);
27+
if (type < 0)
28+
return -EINVAL;
29+
30+
net = get_net_ns_by_fd(attr->query.target_fd);
31+
if (IS_ERR(net))
32+
return PTR_ERR(net);
33+
34+
rcu_read_lock();
35+
attached = rcu_dereference(net->bpf.progs[type]);
36+
if (attached) {
37+
prog_cnt = 1;
38+
prog_id = attached->aux->id;
39+
}
40+
rcu_read_unlock();
41+
42+
put_net(net);
43+
44+
if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
45+
return -EFAULT;
46+
if (copy_to_user(&uattr->query.prog_cnt, &prog_cnt, sizeof(prog_cnt)))
47+
return -EFAULT;
48+
49+
if (!attr->query.prog_cnt || !prog_ids || !prog_cnt)
50+
return 0;
51+
52+
if (copy_to_user(prog_ids, &prog_id, sizeof(u32)))
53+
return -EFAULT;
54+
55+
return 0;
56+
}
57+
58+
int netns_bpf_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
59+
{
60+
enum netns_bpf_attach_type type;
61+
struct net *net;
62+
int ret;
63+
64+
type = to_netns_bpf_attach_type(attr->attach_type);
65+
if (type < 0)
66+
return -EINVAL;
67+
68+
net = current->nsproxy->net_ns;
69+
mutex_lock(&netns_bpf_mutex);
70+
switch (type) {
71+
case NETNS_BPF_FLOW_DISSECTOR:
72+
ret = flow_dissector_bpf_prog_attach(net, prog);
73+
break;
74+
default:
75+
ret = -EINVAL;
76+
break;
77+
}
78+
mutex_unlock(&netns_bpf_mutex);
79+
80+
return ret;
81+
}
82+
83+
/* Must be called with netns_bpf_mutex held. */
84+
static int __netns_bpf_prog_detach(struct net *net,
85+
enum netns_bpf_attach_type type)
86+
{
87+
struct bpf_prog *attached;
88+
89+
attached = rcu_dereference_protected(net->bpf.progs[type],
90+
lockdep_is_held(&netns_bpf_mutex));
91+
if (!attached)
92+
return -ENOENT;
93+
RCU_INIT_POINTER(net->bpf.progs[type], NULL);
94+
bpf_prog_put(attached);
95+
return 0;
96+
}
97+
98+
int netns_bpf_prog_detach(const union bpf_attr *attr)
99+
{
100+
enum netns_bpf_attach_type type;
101+
int ret;
102+
103+
type = to_netns_bpf_attach_type(attr->attach_type);
104+
if (type < 0)
105+
return -EINVAL;
106+
107+
mutex_lock(&netns_bpf_mutex);
108+
ret = __netns_bpf_prog_detach(current->nsproxy->net_ns, type);
109+
mutex_unlock(&netns_bpf_mutex);
110+
111+
return ret;
112+
}
113+
114+
static void __net_exit netns_bpf_pernet_pre_exit(struct net *net)
115+
{
116+
enum netns_bpf_attach_type type;
117+
118+
mutex_lock(&netns_bpf_mutex);
119+
for (type = 0; type < MAX_NETNS_BPF_ATTACH_TYPE; type++)
120+
__netns_bpf_prog_detach(net, type);
121+
mutex_unlock(&netns_bpf_mutex);
122+
}
123+
124+
static struct pernet_operations netns_bpf_pernet_ops __net_initdata = {
125+
.pre_exit = netns_bpf_pernet_pre_exit,
126+
};
127+
128+
static int __init netns_bpf_init(void)
129+
{
130+
return register_pernet_subsys(&netns_bpf_pernet_ops);
131+
}
132+
133+
subsys_initcall(netns_bpf_init);

net/core/flow_dissector.c

Lines changed: 4 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
#endif
3434
#include <linux/bpf-netns.h>
3535

36-
/* Protects updates to netns_bpf */
37-
DEFINE_MUTEX(netns_bpf_mutex);
38-
3936
static void dissector_set_key(struct flow_dissector *flow_dissector,
4037
enum flow_dissector_key_id key_id)
4138
{
@@ -72,52 +69,8 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
7269
}
7370
EXPORT_SYMBOL(skb_flow_dissector_init);
7471

75-
int netns_bpf_prog_query(const union bpf_attr *attr,
76-
union bpf_attr __user *uattr)
77-
{
78-
__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
79-
u32 prog_id, prog_cnt = 0, flags = 0;
80-
enum netns_bpf_attach_type type;
81-
struct bpf_prog *attached;
82-
struct net *net;
83-
84-
if (attr->query.query_flags)
85-
return -EINVAL;
86-
87-
type = to_netns_bpf_attach_type(attr->query.attach_type);
88-
if (type < 0)
89-
return -EINVAL;
90-
91-
net = get_net_ns_by_fd(attr->query.target_fd);
92-
if (IS_ERR(net))
93-
return PTR_ERR(net);
94-
95-
rcu_read_lock();
96-
attached = rcu_dereference(net->bpf.progs[type]);
97-
if (attached) {
98-
prog_cnt = 1;
99-
prog_id = attached->aux->id;
100-
}
101-
rcu_read_unlock();
102-
103-
put_net(net);
104-
105-
if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
106-
return -EFAULT;
107-
if (copy_to_user(&uattr->query.prog_cnt, &prog_cnt, sizeof(prog_cnt)))
108-
return -EFAULT;
109-
110-
if (!attr->query.prog_cnt || !prog_ids || !prog_cnt)
111-
return 0;
112-
113-
if (copy_to_user(prog_ids, &prog_id, sizeof(u32)))
114-
return -EFAULT;
115-
116-
return 0;
117-
}
118-
119-
static int flow_dissector_bpf_prog_attach(struct net *net,
120-
struct bpf_prog *prog)
72+
#ifdef CONFIG_BPF_SYSCALL
73+
int flow_dissector_bpf_prog_attach(struct net *net, struct bpf_prog *prog)
12174
{
12275
enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR;
12376
struct bpf_prog *attached;
@@ -155,76 +108,7 @@ static int flow_dissector_bpf_prog_attach(struct net *net,
155108
bpf_prog_put(attached);
156109
return 0;
157110
}
158-
159-
int netns_bpf_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog)
160-
{
161-
enum netns_bpf_attach_type type;
162-
struct net *net;
163-
int ret;
164-
165-
type = to_netns_bpf_attach_type(attr->attach_type);
166-
if (type < 0)
167-
return -EINVAL;
168-
169-
net = current->nsproxy->net_ns;
170-
mutex_lock(&netns_bpf_mutex);
171-
switch (type) {
172-
case NETNS_BPF_FLOW_DISSECTOR:
173-
ret = flow_dissector_bpf_prog_attach(net, prog);
174-
break;
175-
default:
176-
ret = -EINVAL;
177-
break;
178-
}
179-
mutex_unlock(&netns_bpf_mutex);
180-
181-
return ret;
182-
}
183-
184-
/* Must be called with netns_bpf_mutex held. */
185-
static int __netns_bpf_prog_detach(struct net *net,
186-
enum netns_bpf_attach_type type)
187-
{
188-
struct bpf_prog *attached;
189-
190-
attached = rcu_dereference_protected(net->bpf.progs[type],
191-
lockdep_is_held(&netns_bpf_mutex));
192-
if (!attached)
193-
return -ENOENT;
194-
RCU_INIT_POINTER(net->bpf.progs[type], NULL);
195-
bpf_prog_put(attached);
196-
return 0;
197-
}
198-
199-
int netns_bpf_prog_detach(const union bpf_attr *attr)
200-
{
201-
enum netns_bpf_attach_type type;
202-
int ret;
203-
204-
type = to_netns_bpf_attach_type(attr->attach_type);
205-
if (type < 0)
206-
return -EINVAL;
207-
208-
mutex_lock(&netns_bpf_mutex);
209-
ret = __netns_bpf_prog_detach(current->nsproxy->net_ns, type);
210-
mutex_unlock(&netns_bpf_mutex);
211-
212-
return ret;
213-
}
214-
215-
static void __net_exit netns_bpf_pernet_pre_exit(struct net *net)
216-
{
217-
enum netns_bpf_attach_type type;
218-
219-
mutex_lock(&netns_bpf_mutex);
220-
for (type = 0; type < MAX_NETNS_BPF_ATTACH_TYPE; type++)
221-
__netns_bpf_prog_detach(net, type);
222-
mutex_unlock(&netns_bpf_mutex);
223-
}
224-
225-
static struct pernet_operations netns_bpf_pernet_ops __net_initdata = {
226-
.pre_exit = netns_bpf_pernet_pre_exit,
227-
};
111+
#endif /* CONFIG_BPF_SYSCALL */
228112

229113
/**
230114
* __skb_flow_get_ports - extract the upper layer ports and return them
@@ -1902,7 +1786,6 @@ static int __init init_default_flow_dissectors(void)
19021786
skb_flow_dissector_init(&flow_keys_basic_dissector,
19031787
flow_keys_basic_dissector_keys,
19041788
ARRAY_SIZE(flow_keys_basic_dissector_keys));
1905-
1906-
return register_pernet_subsys(&netns_bpf_pernet_ops);
1789+
return 0;
19071790
}
19081791
core_initcall(init_default_flow_dissectors);

0 commit comments

Comments
 (0)