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
8#include <linux/string.h>8#include <linux/string.h>
9#include <uapi/linux/if_ether.h>9#include <uapi/linux/if_ether.h>
10 10
11struct bpf_prog;
12struct net;
11struct sk_buff;13struct sk_buff;
12 14
13/**15/**
@@ -369,4 +371,8 @@ flow_dissector_init_keys(struct flow_dissector_key_control *key_control, · 355 unmodified lines
369 memset(key_basic, 0, sizeof(*key_basic));371 memset(key_basic, 0, sizeof(*key_basic));
370}372}
371 373
374#ifdef CONFIG_BPF_SYSCALL
375int flow_dissector_bpf_prog_attach(struct net *net, struct bpf_prog *prog);
376#endif /* CONFIG_BPF_SYSCALL */
377
372#endif378#endif
kernel/bpf/Makefile+1−0
@@ -13,6 +13,7 @@ ifeq ($(CONFIG_NET),y) · 12 unmodified lines
13obj-$(CONFIG_BPF_SYSCALL) += devmap.o13obj-$(CONFIG_BPF_SYSCALL) += devmap.o
14obj-$(CONFIG_BPF_SYSCALL) += cpumap.o14obj-$(CONFIG_BPF_SYSCALL) += cpumap.o
15obj-$(CONFIG_BPF_SYSCALL) += offload.o15obj-$(CONFIG_BPF_SYSCALL) += offload.o
16obj-$(CONFIG_BPF_SYSCALL) += net_namespace.o
16endif17endif
17ifeq ($(CONFIG_PERF_EVENTS),y)18ifeq ($(CONFIG_PERF_EVENTS),y)
18obj-$(CONFIG_BPF_SYSCALL) += stackmap.o19obj-$(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 */
12DEFINE_MUTEX(netns_bpf_mutex);
13
14int 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
58int 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. */
84static 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
98int 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
114static 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
124static struct pernet_operations netns_bpf_pernet_ops __net_initdata = {
125 .pre_exit = netns_bpf_pernet_pre_exit,
126};
127
128static int __init netns_bpf_init(void)
129{
130 return register_pernet_subsys(&netns_bpf_pernet_ops);
131}
132
133subsys_initcall(netns_bpf_init);
net/core/flow_dissector.c+4−121
@@ -33,9 +33,6 @@ · 32 unmodified lines
33#endif33#endif
34#include <linux/bpf-netns.h>34#include <linux/bpf-netns.h>
35 35
36/* Protects updates to netns_bpf */
37DEFINE_MUTEX(netns_bpf_mutex);
38
39static void dissector_set_key(struct flow_dissector *flow_dissector,36static void dissector_set_key(struct flow_dissector *flow_dissector,
40 enum flow_dissector_key_id key_id)37 enum flow_dissector_key_id key_id)
41{38{
@@ -72,52 +69,8 @@ void skb_flow_dissector_init(struct flow_dissector *flow_dissector, · 30 unmodified lines
72}69}
73EXPORT_SYMBOL(skb_flow_dissector_init);70EXPORT_SYMBOL(skb_flow_dissector_init);
74 71
75int netns_bpf_prog_query(const union bpf_attr *attr,72#ifdef CONFIG_BPF_SYSCALL
76 union bpf_attr __user *uattr)73int flow_dissector_bpf_prog_attach(struct net *net, struct bpf_prog *prog)
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
119static int flow_dissector_bpf_prog_attach(struct net *net,
120 struct bpf_prog *prog)
121{74{
122 enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR;75 enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR;
123 struct bpf_prog *attached;76 struct bpf_prog *attached;
@@ -155,76 +108,7 @@ static int flow_dissector_bpf_prog_attach(struct net *net, · 31 unmodified lines
155 bpf_prog_put(attached);108 bpf_prog_put(attached);
156 return 0;109 return 0;
157}110}
158 111#endif /* CONFIG_BPF_SYSCALL */
159int 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. */
185static 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
199int 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
215static 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
225static struct pernet_operations netns_bpf_pernet_ops __net_initdata = {
226 .pre_exit = netns_bpf_pernet_pre_exit,
227};
228 112
229/**113/**
230 * __skb_flow_get_ports - extract the upper layer ports and return them114 * __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
1902 skb_flow_dissector_init(&flow_keys_basic_dissector,1786 skb_flow_dissector_init(&flow_keys_basic_dissector,
1903 flow_keys_basic_dissector_keys,1787 flow_keys_basic_dissector_keys,
1904 ARRAY_SIZE(flow_keys_basic_dissector_keys));1788 ARRAY_SIZE(flow_keys_basic_dissector_keys));
1905 1789 return 0;
1906 return register_pernet_subsys(&netns_bpf_pernet_ops);
1907}1790}
1908core_initcall(init_default_flow_dissectors);1791core_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