History

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.

Jakub Sitnicki committed 6 years ago

Commit b27f7bb1 parent a3fd7ce4 files · +144 −121Browse files

Unified · Split

4 files
  1. include/net/flow_dissector.h +6 −0
  2. kernel/bpf/Makefile +1 −0
  3. kernel/bpf/net_namespace.c +133 −0
  4. net/core/flow_dissector.c +4 −121
include/net/flow_dissector.h+6−0
@@ -8,6 +8,8 @@ · 7 unmodified lines
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, · 355 unmodified lines
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+1−0
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_NET),y) · 12 unmodified lines
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+133−0
@@ -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+4−121
@@ -33,9 +33,6 @@ · 32 unmodified lines
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, · 30 unmodified lines
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, · 31 unmodified lines
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) · 1671 unmodified lines
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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t