aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/filter.h
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-03-28 18:58:19 +0100
committerDavid S. Miller <davem@davemloft.net>2014-03-31 00:45:09 -0400
commita3ea269b8bcdbb0c5fa2fd449a436e7987446975 (patch)
tree9e118e381c14f9a065cc4136be2a9bf6e5257dfb /include/linux/filter.h
parentnet: filter: add jited flag to indicate jit compiled filters (diff)
downloadlinux-dev-a3ea269b8bcdbb0c5fa2fd449a436e7987446975.tar.xz
linux-dev-a3ea269b8bcdbb0c5fa2fd449a436e7987446975.zip
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/filter.h')
-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 {
};
#endif
+struct sock_fprog_kern {
+ u16 len;
+ struct sock_filter *filter;
+};
+
struct sk_buff;
struct sock;
-struct sk_filter
-{
+struct sk_filter {
atomic_t refcnt;
u32 jited:1, /* Is our filter JIT'ed? */
len:31; /* Number of filter blocks */
+ struct sock_fprog_kern *orig_prog; /* Original BPF program */
struct rcu_head rcu;
unsigned int (*bpf_func)(const struct sk_buff *skb,
const struct sock_filter *filter);
@@ -42,14 +47,20 @@ static inline unsigned int sk_filter_size(unsigned int proglen)
offsetof(struct sk_filter, insns[proglen]));
}
+#define sk_filter_proglen(fprog) \
+ (fprog->len * sizeof(fprog->filter[0]))
+
extern int sk_filter(struct sock *sk, struct sk_buff *skb);
extern unsigned int sk_run_filter(const struct sk_buff *skb,
const struct sock_filter *filter);
+
extern int sk_unattached_filter_create(struct sk_filter **pfp,
struct sock_fprog *fprog);
extern void sk_unattached_filter_destroy(struct sk_filter *fp);
+
extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
extern int sk_detach_filter(struct sock *sk);
+
extern int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
extern int sk_get_filter(struct sock *sk, struct sock_filter __user *filter, unsigned len);
extern void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);