filter.h 3.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6
/*
 * Linux Socket Filter Data Structures
 */
#ifndef __LINUX_FILTER_H__
#define __LINUX_FILTER_H__

A
Arun Sharma 已提交
7
#include <linux/atomic.h>
8
#include <linux/compat.h>
9
#include <linux/workqueue.h>
10
#include <uapi/linux/filter.h>
11

12 13 14 15 16 17 18 19 20 21
#ifdef CONFIG_COMPAT
/*
 * A struct sock_filter is architecture independent.
 */
struct compat_sock_fprog {
	u16		len;
	compat_uptr_t	filter;		/* struct sock_filter * */
};
#endif

22 23 24 25 26
struct sock_fprog_kern {
	u16			len;
	struct sock_filter	*filter;
};

27 28 29
struct sk_buff;
struct sock;

30
struct sk_filter {
31
	atomic_t		refcnt;
32 33
	u32			jited:1,	/* Is our filter JIT'ed? */
				len:31;		/* Number of filter blocks */
34
	struct sock_fprog_kern	*orig_prog;	/* Original BPF program */
35
	struct rcu_head		rcu;
36 37
	unsigned int		(*bpf_func)(const struct sk_buff *skb,
					    const struct sock_filter *filter);
38 39 40 41
	union {
		struct sock_filter     	insns[0];
		struct work_struct	work;
	};
42 43
};

44
static inline unsigned int sk_filter_size(unsigned int proglen)
45
{
46 47
	return max(sizeof(struct sk_filter),
		   offsetof(struct sk_filter, insns[proglen]));
48 49
}

50 51 52
#define sk_filter_proglen(fprog)			\
		(fprog->len * sizeof(fprog->filter[0]))

53 54 55
int sk_filter(struct sock *sk, struct sk_buff *skb);
unsigned int sk_run_filter(const struct sk_buff *skb,
			   const struct sock_filter *filter);
56

57 58 59
int sk_unattached_filter_create(struct sk_filter **pfp,
				struct sock_fprog *fprog);
void sk_unattached_filter_destroy(struct sk_filter *fp);
60

61 62
int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
int sk_detach_filter(struct sock *sk);
63

64 65 66 67 68 69 70
int sk_chk_filter(struct sock_filter *filter, unsigned int flen);
int sk_get_filter(struct sock *sk, struct sock_filter __user *filter,
		  unsigned int len);
void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to);

void sk_filter_charge(struct sock *sk, struct sk_filter *fp);
void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp);
71 72

#ifdef CONFIG_BPF_JIT
X
Xi Wang 已提交
73
#include <stdarg.h>
74 75 76
#include <linux/linkage.h>
#include <linux/printk.h>

77 78
void bpf_jit_compile(struct sk_filter *fp);
void bpf_jit_free(struct sk_filter *fp);
79 80 81 82

static inline void bpf_jit_dump(unsigned int flen, unsigned int proglen,
				u32 pass, void *image)
{
83
	pr_err("flen=%u proglen=%u pass=%u image=%pK\n",
84 85
	       flen, proglen, pass, image);
	if (image)
86
		print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_OFFSET,
87 88
			       16, 1, image, proglen, false);
}
89 90
#define SK_RUN_FILTER(FILTER, SKB) (*FILTER->bpf_func)(SKB, FILTER->insns)
#else
91
#include <linux/slab.h>
92 93 94 95 96
static inline void bpf_jit_compile(struct sk_filter *fp)
{
}
static inline void bpf_jit_free(struct sk_filter *fp)
{
97
	kfree(fp);
98 99 100 101
}
#define SK_RUN_FILTER(FILTER, SKB) sk_run_filter(SKB, FILTER->insns)
#endif

102 103
static inline int bpf_tell_extensions(void)
{
104
	return SKF_AD_MAX;
105 106
}

107 108 109 110 111 112 113 114 115 116
enum {
	BPF_S_RET_K = 1,
	BPF_S_RET_A,
	BPF_S_ALU_ADD_K,
	BPF_S_ALU_ADD_X,
	BPF_S_ALU_SUB_K,
	BPF_S_ALU_SUB_X,
	BPF_S_ALU_MUL_K,
	BPF_S_ALU_MUL_X,
	BPF_S_ALU_DIV_X,
E
Eric Dumazet 已提交
117 118
	BPF_S_ALU_MOD_K,
	BPF_S_ALU_MOD_X,
119 120 121 122
	BPF_S_ALU_AND_K,
	BPF_S_ALU_AND_X,
	BPF_S_ALU_OR_K,
	BPF_S_ALU_OR_X,
123 124
	BPF_S_ALU_XOR_K,
	BPF_S_ALU_XOR_X,
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
	BPF_S_ALU_LSH_K,
	BPF_S_ALU_LSH_X,
	BPF_S_ALU_RSH_K,
	BPF_S_ALU_RSH_X,
	BPF_S_ALU_NEG,
	BPF_S_LD_W_ABS,
	BPF_S_LD_H_ABS,
	BPF_S_LD_B_ABS,
	BPF_S_LD_W_LEN,
	BPF_S_LD_W_IND,
	BPF_S_LD_H_IND,
	BPF_S_LD_B_IND,
	BPF_S_LD_IMM,
	BPF_S_LDX_W_LEN,
	BPF_S_LDX_B_MSH,
	BPF_S_LDX_IMM,
	BPF_S_MISC_TAX,
	BPF_S_MISC_TXA,
	BPF_S_ALU_DIV_K,
	BPF_S_LD_MEM,
	BPF_S_LDX_MEM,
	BPF_S_ST,
	BPF_S_STX,
	BPF_S_JMP_JA,
	BPF_S_JMP_JEQ_K,
	BPF_S_JMP_JEQ_X,
	BPF_S_JMP_JGE_K,
	BPF_S_JMP_JGE_X,
	BPF_S_JMP_JGT_K,
	BPF_S_JMP_JGT_X,
	BPF_S_JMP_JSET_K,
	BPF_S_JMP_JSET_X,
	/* Ancillary data */
	BPF_S_ANC_PROTOCOL,
	BPF_S_ANC_PKTTYPE,
	BPF_S_ANC_IFINDEX,
	BPF_S_ANC_NLATTR,
	BPF_S_ANC_NLATTR_NEST,
	BPF_S_ANC_MARK,
	BPF_S_ANC_QUEUE,
	BPF_S_ANC_HATYPE,
	BPF_S_ANC_RXHASH,
	BPF_S_ANC_CPU,
J
Jiri Pirko 已提交
168
	BPF_S_ANC_ALU_XOR_X,
169
	BPF_S_ANC_SECCOMP_LD_W,
E
Eric Dumazet 已提交
170 171
	BPF_S_ANC_VLAN_TAG,
	BPF_S_ANC_VLAN_TAG_PRESENT,
172
	BPF_S_ANC_PAY_OFFSET,
173 174
};

L
Linus Torvalds 已提交
175
#endif /* __LINUX_FILTER_H__ */