Go to the documentation of this file.
14 #ifndef __BPF_HELPER_H__
15 #define __BPF_HELPER_H__
17 #include <asm/bitsperlong.h>
19 #include <linux/filter.h>
20 #include <linux/seccomp.h>
21 #include <linux/types.h>
25 #define BPF_LABELS_MAX 256
45 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
47 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL)
48 #define JUMP(labels, label) \
49 BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
51 #define LABEL(labels, label) \
52 BPF_JUMP(BPF_JMP+BPF_JA, FIND_LABEL((labels), (label)), \
54 #define SYSCALL(nr, jt) \
55 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (nr), 0, 1), \
59 #define FIND_LABEL(labels, label) seccomp_bpf_label((labels), #label)
61 #define EXPAND(...) __VA_ARGS__
64 #if __BYTE_ORDER == __LITTLE_ENDIAN
65 #define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
66 #elif __BYTE_ORDER == __BIG_ENDIAN
67 #define LO_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
69 #error "Unknown endianness"
73 #if __BITS_PER_LONG == 32
75 #define JEQ(x, jt) JEQ32(x, EXPAND(jt))
76 #define JNE(x, jt) JNE32(x, EXPAND(jt))
77 #define JGT(x, jt) JGT32(x, EXPAND(jt))
78 #define JLT(x, jt) JLT32(x, EXPAND(jt))
79 #define JGE(x, jt) JGE32(x, EXPAND(jt))
80 #define JLE(x, jt) JLE32(x, EXPAND(jt))
81 #define JA(x, jt) JA32(x, EXPAND(jt))
82 #define ARG(i) ARG_32(i)
84 #elif __BITS_PER_LONG == 64
87 #if __BYTE_ORDER == __LITTLE_ENDIAN
88 #define ENDIAN(_lo, _hi) _lo, _hi
89 #define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)]) + sizeof(__u32)
90 #elif __BYTE_ORDER == __BIG_ENDIAN
91 #define ENDIAN(_lo, _hi) _hi, _lo
92 #define HI_ARG(idx) offsetof(struct seccomp_data, args[(idx)])
103 JEQ64(((union arg64){.u64 = (x)}).lo32, \
104 ((union arg64){.u64 = (x)}).hi32, \
107 JGT64(((union arg64){.u64 = (x)}).lo32, \
108 ((union arg64){.u64 = (x)}).hi32, \
111 JGE64(((union arg64){.u64 = (x)}).lo32, \
112 ((union arg64){.u64 = (x)}).hi32, \
115 JNE64(((union arg64){.u64 = (x)}).lo32, \
116 ((union arg64){.u64 = (x)}).hi32, \
119 JLT64(((union arg64){.u64 = (x)}).lo32, \
120 ((union arg64){.u64 = (x)}).hi32, \
123 JLE64(((union arg64){.u64 = (x)}).lo32, \
124 ((union arg64){.u64 = (x)}).hi32, \
128 JA64(((union arg64){.u64 = (x)}).lo32, \
129 ((union arg64){.u64 = (x)}).hi32, \
131 #define ARG(i) ARG_64(i)
134 #error __BITS_PER_LONG value unusable.
138 #define ARG_32(idx) \
139 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx))
142 #define ARG_64(idx) \
143 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, LO_ARG(idx)), \
144 BPF_STMT(BPF_ST, 0), \
145 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, HI_ARG(idx)), \
148 #define JEQ32(value, jt) \
149 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 0, 1), \
152 #define JNE32(value, jt) \
153 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (value), 1, 0), \
157 #define JEQ64(lo, hi, jt) \
158 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
159 BPF_STMT(BPF_LD+BPF_MEM, 0), \
160 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 0, 2), \
161 BPF_STMT(BPF_LD+BPF_MEM, 1), \
163 BPF_STMT(BPF_LD+BPF_MEM, 1)
165 #define JNE64(lo, hi, jt) \
166 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 5, 0), \
167 BPF_STMT(BPF_LD+BPF_MEM, 0), \
168 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (lo), 2, 0), \
169 BPF_STMT(BPF_LD+BPF_MEM, 1), \
171 BPF_STMT(BPF_LD+BPF_MEM, 1)
173 #define JA32(value, jt) \
174 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (value), 0, 1), \
177 #define JA64(lo, hi, jt) \
178 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (hi), 3, 0), \
179 BPF_STMT(BPF_LD+BPF_MEM, 0), \
180 BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, (lo), 0, 2), \
181 BPF_STMT(BPF_LD+BPF_MEM, 1), \
183 BPF_STMT(BPF_LD+BPF_MEM, 1)
185 #define JGE32(value, jt) \
186 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 0, 1), \
189 #define JLT32(value, jt) \
190 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (value), 1, 0), \
194 #define JGE64(lo, hi, jt) \
195 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
196 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
197 BPF_STMT(BPF_LD+BPF_MEM, 0), \
198 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (lo), 0, 2), \
199 BPF_STMT(BPF_LD+BPF_MEM, 1), \
201 BPF_STMT(BPF_LD+BPF_MEM, 1)
203 #define JLT64(lo, hi, jt) \
204 BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, (hi), 0, 4), \
205 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
206 BPF_STMT(BPF_LD+BPF_MEM, 0), \
207 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
208 BPF_STMT(BPF_LD+BPF_MEM, 1), \
210 BPF_STMT(BPF_LD+BPF_MEM, 1)
212 #define JGT32(value, jt) \
213 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 0, 1), \
216 #define JLE32(value, jt) \
217 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (value), 1, 0), \
221 #define JGT64(lo, hi, jt) \
222 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 4, 0), \
223 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 5), \
224 BPF_STMT(BPF_LD+BPF_MEM, 0), \
225 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 0, 2), \
226 BPF_STMT(BPF_LD+BPF_MEM, 1), \
228 BPF_STMT(BPF_LD+BPF_MEM, 1)
230 #define JLE64(lo, hi, jt) \
231 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (hi), 6, 0), \
232 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (hi), 0, 3), \
233 BPF_STMT(BPF_LD+BPF_MEM, 0), \
234 BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, (lo), 2, 0), \
235 BPF_STMT(BPF_LD+BPF_MEM, 1), \
237 BPF_STMT(BPF_LD+BPF_MEM, 1)
239 #define LOAD_SYSCALL_NR \
240 BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \
241 offsetof(struct seccomp_data, nr))