aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-03-28 13:58:19 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-31 00:45:09 -0400
commita3ea269b8bcdbb0c5fa2fd449a436e7987446975 (patch)
tree9e118e381c14f9a065cc4136be2a9bf6e5257dfb /include/linux
parentf8bbbfc3b97f4c7a6c7c23185e520b22bfc3a21d (diff)
net: filter: keep original BPF program around
In order to open up the possibility to internally transform a BPF program into an alternative and possibly non-trivial reversible representation, we need to keep the original BPF program around, so that it can be passed back to user space w/o the need of a complex decoder. The reason for that use case resides in commit a8fc92778080 ("sk-filter: Add ability to get socket filter program (v2)"), that is, the ability to retrieve the currently attached BPF filter from a given socket used mainly by the checkpoint-restore project, for example. Therefore, we add two helpers sk_{store,release}_orig_filter for taking care of that. In the sk_unattached_filter_create() case, there's no such possibility/requirement to retrieve a loaded BPF program. Therefore, we can spare us the work in that case. This approach will simplify and slightly speed up both, sk_get_filter() and sock_diag_put_filterinfo() handlers as we won't need to successively decode filters anymore through sk_decode_filter(). As we still need sk_decode_filter() later on, we're keeping it around. Joint work with Alexei Starovoitov. Signed-off-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Cc: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/filter.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index e65e23087367..93a9792e27bc 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -19,14 +19,19 @@ struct compat_sock_fprog {
19}; 19};
20#endif 20#endif
21 21
22struct sock_fprog_kern {
23 u16 len;
24 struct sock_filter *filter;
25};
26
22struct sk_buff; 27struct sk_buff;
23struct sock; 28struct sock;
24 29
25struct sk_filter 30struct sk_filter {
26{
27 atomic_t refcnt; 31 atomic_t refcnt;
28 u32 jited:1, /* Is our filter JIT'ed? */ 32 u32 jited:1, /* Is our filter JIT'ed? */
29 len:31; /* Number of filter blocks */ 33 len:31; /* Number of filter blocks */
34 struct sock_fprog_kern *orig_prog; /* Original BPF program */
30 struct rcu_head rcu; 35 struct rcu_head rcu;
31 unsigned int (*bpf_func)(const struct sk_buff *skb, 36 unsigned int (*bpf_func)(const struct sk_buff *skb,
32 const struct sock_filter *filter); 37 const struct sock_filter *filter);
@@ -42,14 +47,20 @@ static inline unsigned int sk_filter_size(unsigned int proglen)
42 offsetof(struct sk_filter, insns[proglen])); 47 offsetof(struct sk_filter, insns[proglen]));
43} 48}
44 49
50#define sk_filter_proglen(fprog) \
51 (fprog->len * sizeof(fprog->filter[0]))
52
45extern int sk_filter(struct sock *sk, struct sk_buff *skb); 53extern int sk_filter(struct sock *sk, struct sk_buff *skb);
46extern unsigned int sk_run_filter(const struct sk_buff *skb, 54extern unsigned int sk_run_filter(const struct sk_buff *skb,
47 const struct sock_filter *filter); 55 const struct sock_filter *filter);
56
48extern int sk_unattached_filter_create(struct sk_filter **pfp, 57extern int sk_unattached_filter_create(struct sk_filter **pfp,
49 struct sock_fprog *fprog); 58 struct sock_fprog *fprog);
50extern void sk_unattached_filter_destroy(struct sk_filter *fp); 59extern void sk_unattached_filter_destroy(struct sk_filter *fp);
60
51extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); 61extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
52extern int sk_detach_filter(struct sock *sk); 62extern int sk_detach_filter(struct sock *sk);
63
53extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen); 64extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
54extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len); 65extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len);
55extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to); 66extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);