aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2014-05-23 12:44:00 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-23 16:48:06 -0400
commit10f18e0ba1ea7eb004bbaecb4748b1eb28802d24 (patch)
treea536357e238b2f9389f9d9c88100c10773102557 /lib
parent04caa489301c5e01ac4e5d1c13abcecb2041300b (diff)
net: filter: improve test case framework
This patch simplifies and refactors the test case code a bit and also adds a summary of all test that passed or failed in the kernel log, so that it's easier to spot if something has failed. Future work could further extend the test framework to also support different input 'stimuli' i.e. related structures to seccomp. Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/test_bpf.c388
1 files changed, 233 insertions, 155 deletions
diff --git a/lib/test_bpf.c b/lib/test_bpf.c
index e03991ea8cc2..da34e337f45b 100644
--- a/lib/test_bpf.c
+++ b/lib/test_bpf.c
@@ -22,12 +22,14 @@
22#include <linux/netdevice.h> 22#include <linux/netdevice.h>
23#include <linux/if_vlan.h> 23#include <linux/if_vlan.h>
24 24
25/* General test specific settings */
25#define MAX_SUBTESTS 3 26#define MAX_SUBTESTS 3
27#define MAX_TESTRUNS 10000
26#define MAX_DATA 128 28#define MAX_DATA 128
27#define MAX_INSNS 512 29#define MAX_INSNS 512
28#define MAX_K 0xffffFFFF 30#define MAX_K 0xffffFFFF
29 31
30/* define few constants used to init test 'skb' */ 32/* Few constants used to init test 'skb' */
31#define SKB_TYPE 3 33#define SKB_TYPE 3
32#define SKB_MARK 0x1234aaaa 34#define SKB_MARK 0x1234aaaa
33#define SKB_HASH 0x1234aaab 35#define SKB_HASH 0x1234aaab
@@ -36,18 +38,29 @@
36#define SKB_DEV_IFINDEX 577 38#define SKB_DEV_IFINDEX 577
37#define SKB_DEV_TYPE 588 39#define SKB_DEV_TYPE 588
38 40
39/* redefine REGs to make tests less verbose */ 41/* Redefine REGs to make tests less verbose */
40#define R0 BPF_REG_0 42#define R0 BPF_REG_0
41#define R1 BPF_REG_1 43#define R1 BPF_REG_1
42#define R2 BPF_REG_2 44#define R2 BPF_REG_2
43#define R3 BPF_REG_3 45#define R3 BPF_REG_3
44#define R4 BPF_REG_4 46#define R4 BPF_REG_4
45#define R5 BPF_REG_5 47#define R5 BPF_REG_5
46#define R6 BPF_REG_6 48#define R6 BPF_REG_6
47#define R7 BPF_REG_7 49#define R7 BPF_REG_7
48#define R8 BPF_REG_8 50#define R8 BPF_REG_8
49#define R9 BPF_REG_9 51#define R9 BPF_REG_9
50#define R10 BPF_REG_10 52#define R10 BPF_REG_10
53
54/* Flags that can be passed to test cases */
55#define FLAG_NO_DATA BIT(0)
56#define FLAG_EXPECTED_FAIL BIT(1)
57
58enum {
59 CLASSIC = BIT(6), /* Old BPF instructions only. */
60 INTERNAL = BIT(7), /* Extended instruction set. */
61};
62
63#define TEST_TYPE_MASK (CLASSIC | INTERNAL)
51 64
52struct bpf_test { 65struct bpf_test {
53 const char *descr; 66 const char *descr;
@@ -55,12 +68,7 @@ struct bpf_test {
55 struct sock_filter insns[MAX_INSNS]; 68 struct sock_filter insns[MAX_INSNS];
56 struct sock_filter_int insns_int[MAX_INSNS]; 69 struct sock_filter_int insns_int[MAX_INSNS];
57 } u; 70 } u;
58 enum { 71 __u8 aux;
59 NO_DATA,
60 EXPECTED_FAIL,
61 SKB,
62 SKB_INT
63 } data_type;
64 __u8 data[MAX_DATA]; 72 __u8 data[MAX_DATA];
65 struct { 73 struct {
66 int data_size; 74 int data_size;
@@ -84,7 +92,7 @@ static struct bpf_test tests[] = {
84 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1), 92 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1),
85 BPF_STMT(BPF_RET | BPF_A, 0) 93 BPF_STMT(BPF_RET | BPF_A, 0)
86 }, 94 },
87 SKB, 95 CLASSIC,
88 { 10, 20, 30, 40, 50 }, 96 { 10, 20, 30, 40, 50 },
89 { { 2, 10 }, { 3, 20 }, { 4, 30 } }, 97 { { 2, 10 }, { 3, 20 }, { 4, 30 } },
90 }, 98 },
@@ -96,7 +104,7 @@ static struct bpf_test tests[] = {
96 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 104 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
97 BPF_STMT(BPF_RET | BPF_A, 0) /* A == len * 2 */ 105 BPF_STMT(BPF_RET | BPF_A, 0) /* A == len * 2 */
98 }, 106 },
99 SKB, 107 CLASSIC,
100 { 10, 20, 30, 40, 50 }, 108 { 10, 20, 30, 40, 50 },
101 { { 1, 2 }, { 3, 6 }, { 4, 8 } }, 109 { { 1, 2 }, { 3, 6 }, { 4, 8 } },
102 }, 110 },
@@ -111,7 +119,7 @@ static struct bpf_test tests[] = {
111 BPF_STMT(BPF_ALU | BPF_MUL | BPF_K, 3), 119 BPF_STMT(BPF_ALU | BPF_MUL | BPF_K, 3),
112 BPF_STMT(BPF_RET | BPF_A, 0) 120 BPF_STMT(BPF_RET | BPF_A, 0)
113 }, 121 },
114 0, 122 CLASSIC | FLAG_NO_DATA,
115 { }, 123 { },
116 { { 0, 0xfffffffd } } 124 { { 0, 0xfffffffd } }
117 }, 125 },
@@ -129,7 +137,7 @@ static struct bpf_test tests[] = {
129 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 137 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
130 BPF_STMT(BPF_RET | BPF_A, 0) 138 BPF_STMT(BPF_RET | BPF_A, 0)
131 }, 139 },
132 0, 140 CLASSIC | FLAG_NO_DATA,
133 { }, 141 { },
134 { { 0, 0x40000001 } } 142 { { 0, 0x40000001 } }
135 }, 143 },
@@ -145,7 +153,7 @@ static struct bpf_test tests[] = {
145 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 153 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
146 BPF_STMT(BPF_RET | BPF_A, 0) 154 BPF_STMT(BPF_RET | BPF_A, 0)
147 }, 155 },
148 0, 156 CLASSIC | FLAG_NO_DATA,
149 { }, 157 { },
150 { { 0, 0x800000ff }, { 1, 0x800000ff } }, 158 { { 0, 0x800000ff }, { 1, 0x800000ff } },
151 }, 159 },
@@ -156,7 +164,7 @@ static struct bpf_test tests[] = {
156 BPF_STMT(BPF_LD | BPF_H | BPF_IND, MAX_K), 164 BPF_STMT(BPF_LD | BPF_H | BPF_IND, MAX_K),
157 BPF_STMT(BPF_RET | BPF_K, 1) 165 BPF_STMT(BPF_RET | BPF_K, 1)
158 }, 166 },
159 SKB, 167 CLASSIC,
160 { }, 168 { },
161 { { 1, 0 }, { 10, 0 }, { 60, 0 } }, 169 { { 1, 0 }, { 10, 0 }, { 60, 0 } },
162 }, 170 },
@@ -166,7 +174,7 @@ static struct bpf_test tests[] = {
166 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 1000), 174 BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 1000),
167 BPF_STMT(BPF_RET | BPF_K, 1) 175 BPF_STMT(BPF_RET | BPF_K, 1)
168 }, 176 },
169 SKB, 177 CLASSIC,
170 { }, 178 { },
171 { { 1, 0 }, { 10, 0 }, { 60, 0 } }, 179 { { 1, 0 }, { 10, 0 }, { 60, 0 } },
172 }, 180 },
@@ -179,7 +187,7 @@ static struct bpf_test tests[] = {
179 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 187 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
180 BPF_STMT(BPF_RET | BPF_A, 0) 188 BPF_STMT(BPF_RET | BPF_A, 0)
181 }, 189 },
182 SKB, 190 CLASSIC,
183 { 1, 2, 3 }, 191 { 1, 2, 3 },
184 { { 1, 0 }, { 2, 3 } }, 192 { { 1, 0 }, { 2, 3 } },
185 }, 193 },
@@ -193,7 +201,7 @@ static struct bpf_test tests[] = {
193 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0), 201 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
194 BPF_STMT(BPF_RET | BPF_A, 0) 202 BPF_STMT(BPF_RET | BPF_A, 0)
195 }, 203 },
196 SKB, 204 CLASSIC,
197 { 1, 2, 3, 0xff }, 205 { 1, 2, 3, 0xff },
198 { { 1, 1 }, { 3, 3 }, { 4, 0xff } }, 206 { { 1, 1 }, { 3, 3 }, { 4, 0xff } },
199 }, 207 },
@@ -206,7 +214,7 @@ static struct bpf_test tests[] = {
206 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 214 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0),
207 BPF_STMT(BPF_RET | BPF_A, 0) 215 BPF_STMT(BPF_RET | BPF_A, 0)
208 }, 216 },
209 SKB, 217 CLASSIC,
210 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 }, 218 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 },
211 { { 15, 0 }, { 16, 3 } }, 219 { { 15, 0 }, { 16, 3 } },
212 }, 220 },
@@ -220,7 +228,7 @@ static struct bpf_test tests[] = {
220 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0), 228 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 0),
221 BPF_STMT(BPF_RET | BPF_A, 0) 229 BPF_STMT(BPF_RET | BPF_A, 0)
222 }, 230 },
223 SKB, 231 CLASSIC,
224 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 }, 232 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 },
225 { { 14, 0 }, { 15, 1 }, { 17, 3 } }, 233 { { 14, 0 }, { 15, 1 }, { 17, 3 } },
226 }, 234 },
@@ -241,7 +249,7 @@ static struct bpf_test tests[] = {
241 BPF_STMT(BPF_RET | BPF_K, 1), 249 BPF_STMT(BPF_RET | BPF_K, 1),
242 BPF_STMT(BPF_RET | BPF_A, 0) 250 BPF_STMT(BPF_RET | BPF_A, 0)
243 }, 251 },
244 SKB, 252 CLASSIC,
245 { }, 253 { },
246 { { 1, 3 }, { 10, 3 } }, 254 { { 1, 3 }, { 10, 3 } },
247 }, 255 },
@@ -252,7 +260,7 @@ static struct bpf_test tests[] = {
252 SKF_AD_OFF + SKF_AD_MARK), 260 SKF_AD_OFF + SKF_AD_MARK),
253 BPF_STMT(BPF_RET | BPF_A, 0) 261 BPF_STMT(BPF_RET | BPF_A, 0)
254 }, 262 },
255 SKB, 263 CLASSIC,
256 { }, 264 { },
257 { { 1, SKB_MARK}, { 10, SKB_MARK} }, 265 { { 1, SKB_MARK}, { 10, SKB_MARK} },
258 }, 266 },
@@ -263,7 +271,7 @@ static struct bpf_test tests[] = {
263 SKF_AD_OFF + SKF_AD_RXHASH), 271 SKF_AD_OFF + SKF_AD_RXHASH),
264 BPF_STMT(BPF_RET | BPF_A, 0) 272 BPF_STMT(BPF_RET | BPF_A, 0)
265 }, 273 },
266 SKB, 274 CLASSIC,
267 { }, 275 { },
268 { { 1, SKB_HASH}, { 10, SKB_HASH} }, 276 { { 1, SKB_HASH}, { 10, SKB_HASH} },
269 }, 277 },
@@ -274,7 +282,7 @@ static struct bpf_test tests[] = {
274 SKF_AD_OFF + SKF_AD_QUEUE), 282 SKF_AD_OFF + SKF_AD_QUEUE),
275 BPF_STMT(BPF_RET | BPF_A, 0) 283 BPF_STMT(BPF_RET | BPF_A, 0)
276 }, 284 },
277 SKB, 285 CLASSIC,
278 { }, 286 { },
279 { { 1, SKB_QUEUE_MAP }, { 10, SKB_QUEUE_MAP } }, 287 { { 1, SKB_QUEUE_MAP }, { 10, SKB_QUEUE_MAP } },
280 }, 288 },
@@ -293,7 +301,7 @@ static struct bpf_test tests[] = {
293 BPF_STMT(BPF_MISC | BPF_TXA, 0), 301 BPF_STMT(BPF_MISC | BPF_TXA, 0),
294 BPF_STMT(BPF_RET | BPF_A, 0) 302 BPF_STMT(BPF_RET | BPF_A, 0)
295 }, 303 },
296 SKB, 304 CLASSIC,
297 { 10, 20, 30 }, 305 { 10, 20, 30 },
298 { { 10, ETH_P_IP }, { 100, ETH_P_IP } }, 306 { { 10, ETH_P_IP }, { 100, ETH_P_IP } },
299 }, 307 },
@@ -304,7 +312,7 @@ static struct bpf_test tests[] = {
304 SKF_AD_OFF + SKF_AD_VLAN_TAG), 312 SKF_AD_OFF + SKF_AD_VLAN_TAG),
305 BPF_STMT(BPF_RET | BPF_A, 0) 313 BPF_STMT(BPF_RET | BPF_A, 0)
306 }, 314 },
307 SKB, 315 CLASSIC,
308 { }, 316 { },
309 { 317 {
310 { 1, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT }, 318 { 1, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT },
@@ -318,7 +326,7 @@ static struct bpf_test tests[] = {
318 SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT), 326 SKF_AD_OFF + SKF_AD_VLAN_TAG_PRESENT),
319 BPF_STMT(BPF_RET | BPF_A, 0) 327 BPF_STMT(BPF_RET | BPF_A, 0)
320 }, 328 },
321 SKB, 329 CLASSIC,
322 { }, 330 { },
323 { 331 {
324 { 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) }, 332 { 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) },
@@ -332,7 +340,7 @@ static struct bpf_test tests[] = {
332 SKF_AD_OFF + SKF_AD_IFINDEX), 340 SKF_AD_OFF + SKF_AD_IFINDEX),
333 BPF_STMT(BPF_RET | BPF_A, 0) 341 BPF_STMT(BPF_RET | BPF_A, 0)
334 }, 342 },
335 SKB, 343 CLASSIC,
336 { }, 344 { },
337 { { 1, SKB_DEV_IFINDEX }, { 10, SKB_DEV_IFINDEX } }, 345 { { 1, SKB_DEV_IFINDEX }, { 10, SKB_DEV_IFINDEX } },
338 }, 346 },
@@ -343,7 +351,7 @@ static struct bpf_test tests[] = {
343 SKF_AD_OFF + SKF_AD_HATYPE), 351 SKF_AD_OFF + SKF_AD_HATYPE),
344 BPF_STMT(BPF_RET | BPF_A, 0) 352 BPF_STMT(BPF_RET | BPF_A, 0)
345 }, 353 },
346 SKB, 354 CLASSIC,
347 { }, 355 { },
348 { { 1, SKB_DEV_TYPE }, { 10, SKB_DEV_TYPE } }, 356 { { 1, SKB_DEV_TYPE }, { 10, SKB_DEV_TYPE } },
349 }, 357 },
@@ -358,7 +366,7 @@ static struct bpf_test tests[] = {
358 BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0), 366 BPF_STMT(BPF_ALU | BPF_SUB | BPF_X, 0),
359 BPF_STMT(BPF_RET | BPF_A, 0) 367 BPF_STMT(BPF_RET | BPF_A, 0)
360 }, 368 },
361 SKB, 369 CLASSIC,
362 { }, 370 { },
363 { { 1, 0 }, { 10, 0 } }, 371 { { 1, 0 }, { 10, 0 } },
364 }, 372 },
@@ -372,7 +380,7 @@ static struct bpf_test tests[] = {
372 SKF_AD_OFF + SKF_AD_NLATTR), 380 SKF_AD_OFF + SKF_AD_NLATTR),
373 BPF_STMT(BPF_RET | BPF_A, 0) 381 BPF_STMT(BPF_RET | BPF_A, 0)
374 }, 382 },
375 SKB, 383 CLASSIC,
376 { 0xff, 4, 0, 2, 0, 4, 0, 3, 0 }, 384 { 0xff, 4, 0, 2, 0, 4, 0, 3, 0 },
377 { { 4, 0 }, { 20, 5 } }, 385 { { 4, 0 }, { 20, 5 } },
378 }, 386 },
@@ -406,7 +414,7 @@ static struct bpf_test tests[] = {
406 SKF_AD_OFF + SKF_AD_NLATTR_NEST), 414 SKF_AD_OFF + SKF_AD_NLATTR_NEST),
407 BPF_STMT(BPF_RET | BPF_A, 0) 415 BPF_STMT(BPF_RET | BPF_A, 0)
408 }, 416 },
409 SKB, 417 CLASSIC,
410 { 0xff, 12, 0, 1, 0, 4, 0, 2, 0, 4, 0, 3, 0 }, 418 { 0xff, 12, 0, 1, 0, 4, 0, 2, 0, 4, 0, 3, 0 },
411 { { 4, 0 }, { 20, 9 } }, 419 { { 4, 0 }, { 20, 9 } },
412 }, 420 },
@@ -425,7 +433,7 @@ static struct bpf_test tests[] = {
425 SKF_AD_OFF + SKF_AD_PAY_OFFSET), 433 SKF_AD_OFF + SKF_AD_PAY_OFFSET),
426 BPF_STMT(BPF_RET | BPF_A, 0) 434 BPF_STMT(BPF_RET | BPF_A, 0)
427 }, 435 },
428 SKB, 436 CLASSIC,
429 /* 00:00:00:00:00:00 > 00:00:00:00:00:00, ethtype IPv4 (0x0800), 437 /* 00:00:00:00:00:00 > 00:00:00:00:00:00, ethtype IPv4 (0x0800),
430 * length 98: 127.0.0.1 > 127.0.0.1: ICMP echo request, 438 * length 98: 127.0.0.1 > 127.0.0.1: ICMP echo request,
431 * id 9737, seq 1, length 64 439 * id 9737, seq 1, length 64
@@ -446,7 +454,7 @@ static struct bpf_test tests[] = {
446 SKF_AD_OFF + SKF_AD_ALU_XOR_X), 454 SKF_AD_OFF + SKF_AD_ALU_XOR_X),
447 BPF_STMT(BPF_RET | BPF_A, 0) 455 BPF_STMT(BPF_RET | BPF_A, 0)
448 }, 456 },
449 SKB, 457 CLASSIC,
450 { }, 458 { },
451 { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } }, 459 { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } },
452 }, 460 },
@@ -468,7 +476,7 @@ static struct bpf_test tests[] = {
468 BPF_STMT(BPF_ALU | BPF_XOR | BPF_X, 0), 476 BPF_STMT(BPF_ALU | BPF_XOR | BPF_X, 0),
469 BPF_STMT(BPF_RET | BPF_A, 0) 477 BPF_STMT(BPF_RET | BPF_A, 0)
470 }, 478 },
471 SKB, 479 CLASSIC,
472 { }, 480 { },
473 { { 1, 0x80000001 }, { 2, 0x80000002 }, { 60, 0x80000000 ^ 60 } } 481 { { 1, 0x80000001 }, { 2, 0x80000002 }, { 60, 0x80000000 ^ 60 } }
474 }, 482 },
@@ -481,7 +489,7 @@ static struct bpf_test tests[] = {
481 BPF_STMT(BPF_RET | BPF_K, 1), 489 BPF_STMT(BPF_RET | BPF_K, 1),
482 BPF_STMT(BPF_RET | BPF_K, MAX_K) 490 BPF_STMT(BPF_RET | BPF_K, MAX_K)
483 }, 491 },
484 SKB, 492 CLASSIC,
485 { 3, 3, 3, 3, 3 }, 493 { 3, 3, 3, 3, 3 },
486 { { 1, 0 }, { 3, 1 }, { 4, MAX_K } }, 494 { { 1, 0 }, { 3, 1 }, { 4, MAX_K } },
487 }, 495 },
@@ -494,7 +502,7 @@ static struct bpf_test tests[] = {
494 BPF_STMT(BPF_RET | BPF_K, 1), 502 BPF_STMT(BPF_RET | BPF_K, 1),
495 BPF_STMT(BPF_RET | BPF_K, MAX_K) 503 BPF_STMT(BPF_RET | BPF_K, MAX_K)
496 }, 504 },
497 SKB, 505 CLASSIC,
498 { 4, 4, 4, 3, 3 }, 506 { 4, 4, 4, 3, 3 },
499 { { 2, 0 }, { 3, 1 }, { 4, MAX_K } }, 507 { { 2, 0 }, { 3, 1 }, { 4, MAX_K } },
500 }, 508 },
@@ -513,7 +521,7 @@ static struct bpf_test tests[] = {
513 BPF_STMT(BPF_RET | BPF_K, 40), 521 BPF_STMT(BPF_RET | BPF_K, 40),
514 BPF_STMT(BPF_RET | BPF_K, MAX_K) 522 BPF_STMT(BPF_RET | BPF_K, MAX_K)
515 }, 523 },
516 SKB, 524 CLASSIC,
517 { 1, 2, 3, 4, 5 }, 525 { 1, 2, 3, 4, 5 },
518 { { 1, 20 }, { 3, 40 }, { 5, MAX_K } }, 526 { { 1, 20 }, { 3, 40 }, { 5, MAX_K } },
519 }, 527 },
@@ -545,7 +553,7 @@ static struct bpf_test tests[] = {
545 BPF_STMT(BPF_RET | BPF_K, 30), 553 BPF_STMT(BPF_RET | BPF_K, 30),
546 BPF_STMT(BPF_RET | BPF_K, MAX_K) 554 BPF_STMT(BPF_RET | BPF_K, MAX_K)
547 }, 555 },
548 SKB, 556 CLASSIC,
549 { 0, 0xAA, 0x55, 1 }, 557 { 0, 0xAA, 0x55, 1 },
550 { { 4, 10 }, { 5, 20 }, { 6, MAX_K } }, 558 { { 4, 10 }, { 5, 20 }, { 6, MAX_K } },
551 }, 559 },
@@ -577,7 +585,7 @@ static struct bpf_test tests[] = {
577 { 0x06, 0, 0, 0x0000ffff }, 585 { 0x06, 0, 0, 0x0000ffff },
578 { 0x06, 0, 0, 0x00000000 }, 586 { 0x06, 0, 0, 0x00000000 },
579 }, 587 },
580 SKB, 588 CLASSIC,
581 /* 3c:07:54:43:e5:76 > 10:bf:48:d6:43:d6, ethertype IPv4(0x0800) 589 /* 3c:07:54:43:e5:76 > 10:bf:48:d6:43:d6, ethertype IPv4(0x0800)
582 * length 114: 10.1.1.149.49700 > 10.1.2.10.22: Flags [P.], 590 * length 114: 10.1.1.149.49700 > 10.1.2.10.22: Flags [P.],
583 * seq 1305692979:1305693027, ack 3650467037, win 65535, 591 * seq 1305692979:1305693027, ack 3650467037, win 65535,
@@ -635,7 +643,7 @@ static struct bpf_test tests[] = {
635 { 0x06, 0, 0, 0x0000ffff }, 643 { 0x06, 0, 0, 0x0000ffff },
636 { 0x06, 0, 0, 0x00000000 }, 644 { 0x06, 0, 0, 0x00000000 },
637 }, 645 },
638 SKB, 646 CLASSIC,
639 { 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6, 647 { 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6,
640 0x3c, 0x07, 0x54, 0x43, 0xe5, 0x76, 648 0x3c, 0x07, 0x54, 0x43, 0xe5, 0x76,
641 0x08, 0x00, 649 0x08, 0x00,
@@ -654,8 +662,8 @@ static struct bpf_test tests[] = {
654 BPF_STMT(BPF_MISC | BPF_TXA, 0), 662 BPF_STMT(BPF_MISC | BPF_TXA, 0),
655 BPF_STMT(BPF_RET | BPF_A, 0) 663 BPF_STMT(BPF_RET | BPF_A, 0)
656 }, 664 },
657 SKB, 665 CLASSIC,
658 {}, 666 { },
659 { {1, 0}, {2, 0} }, 667 { {1, 0}, {2, 0} },
660 }, 668 },
661 { 669 {
@@ -670,7 +678,7 @@ static struct bpf_test tests[] = {
670 BPF_ALU64_REG(BPF_MOV, R0, R1), 678 BPF_ALU64_REG(BPF_MOV, R0, R1),
671 BPF_EXIT_INSN(), 679 BPF_EXIT_INSN(),
672 }, 680 },
673 SKB_INT, 681 INTERNAL,
674 { }, 682 { },
675 { { 0, 0xfffffffd } } 683 { { 0, 0xfffffffd } }
676 }, 684 },
@@ -686,7 +694,7 @@ static struct bpf_test tests[] = {
686 BPF_ALU64_IMM(BPF_MOV, R0, 1), 694 BPF_ALU64_IMM(BPF_MOV, R0, 1),
687 BPF_EXIT_INSN(), 695 BPF_EXIT_INSN(),
688 }, 696 },
689 SKB_INT, 697 INTERNAL,
690 { }, 698 { },
691 { { 0, 1 } } 699 { { 0, 1 } }
692 }, 700 },
@@ -703,7 +711,7 @@ static struct bpf_test tests[] = {
703 BPF_ALU32_IMM(BPF_MOV, R0, 1), 711 BPF_ALU32_IMM(BPF_MOV, R0, 1),
704 BPF_EXIT_INSN(), 712 BPF_EXIT_INSN(),
705 }, 713 },
706 SKB_INT, 714 INTERNAL,
707 { }, 715 { },
708 { { 0, 1 } } 716 { { 0, 1 } }
709 }, 717 },
@@ -720,7 +728,7 @@ static struct bpf_test tests[] = {
720 BPF_ALU32_IMM(BPF_MOV, R0, 1), 728 BPF_ALU32_IMM(BPF_MOV, R0, 1),
721 BPF_EXIT_INSN(), 729 BPF_EXIT_INSN(),
722 }, 730 },
723 SKB_INT, 731 INTERNAL,
724 { }, 732 { },
725 { { 0, 1 } } 733 { { 0, 1 } }
726 }, 734 },
@@ -882,7 +890,7 @@ static struct bpf_test tests[] = {
882 BPF_ALU64_REG(BPF_MOV, R0, R9), 890 BPF_ALU64_REG(BPF_MOV, R0, R9),
883 BPF_EXIT_INSN(), 891 BPF_EXIT_INSN(),
884 }, 892 },
885 SKB_INT, 893 INTERNAL,
886 { }, 894 { },
887 { { 0, 2957380 } } 895 { { 0, 2957380 } }
888 }, 896 },
@@ -1028,7 +1036,7 @@ static struct bpf_test tests[] = {
1028 BPF_ALU32_REG(BPF_MOV, R0, R9), 1036 BPF_ALU32_REG(BPF_MOV, R0, R9),
1029 BPF_EXIT_INSN(), 1037 BPF_EXIT_INSN(),
1030 }, 1038 },
1031 SKB_INT, 1039 INTERNAL,
1032 { }, 1040 { },
1033 { { 0, 2957380 } } 1041 { { 0, 2957380 } }
1034 }, 1042 },
@@ -1161,7 +1169,7 @@ static struct bpf_test tests[] = {
1161 BPF_ALU64_REG(BPF_SUB, R0, R9), 1169 BPF_ALU64_REG(BPF_SUB, R0, R9),
1162 BPF_EXIT_INSN(), 1170 BPF_EXIT_INSN(),
1163 }, 1171 },
1164 SKB_INT, 1172 INTERNAL,
1165 { }, 1173 { },
1166 { { 0, 11 } } 1174 { { 0, 11 } }
1167 }, 1175 },
@@ -1227,7 +1235,7 @@ static struct bpf_test tests[] = {
1227 BPF_ALU64_IMM(BPF_MOV, R0, 1), 1235 BPF_ALU64_IMM(BPF_MOV, R0, 1),
1228 BPF_EXIT_INSN(), 1236 BPF_EXIT_INSN(),
1229 }, 1237 },
1230 SKB_INT, 1238 INTERNAL,
1231 { }, 1239 { },
1232 { { 0, 1 } } 1240 { { 0, 1 } }
1233 }, 1241 },
@@ -1289,7 +1297,7 @@ static struct bpf_test tests[] = {
1289 BPF_ALU64_REG(BPF_MOV, R0, R2), 1297 BPF_ALU64_REG(BPF_MOV, R0, R2),
1290 BPF_EXIT_INSN(), 1298 BPF_EXIT_INSN(),
1291 }, 1299 },
1292 SKB_INT, 1300 INTERNAL,
1293 { }, 1301 { },
1294 { { 0, 0x35d97ef2 } } 1302 { { 0, 0x35d97ef2 } }
1295 }, 1303 },
@@ -1309,7 +1317,7 @@ static struct bpf_test tests[] = {
1309 BPF_ALU64_IMM(BPF_MOV, R0, -1), 1317 BPF_ALU64_IMM(BPF_MOV, R0, -1),
1310 BPF_EXIT_INSN(), 1318 BPF_EXIT_INSN(),
1311 }, 1319 },
1312 SKB_INT, 1320 INTERNAL,
1313 { }, 1321 { },
1314 { { 0, -1 } } 1322 { { 0, -1 } }
1315 }, 1323 },
@@ -1326,7 +1334,7 @@ static struct bpf_test tests[] = {
1326 BPF_LD_IND(BPF_B, R8, -70), 1334 BPF_LD_IND(BPF_B, R8, -70),
1327 BPF_EXIT_INSN(), 1335 BPF_EXIT_INSN(),
1328 }, 1336 },
1329 SKB_INT, 1337 INTERNAL,
1330 { 10, 20, 30, 40, 50 }, 1338 { 10, 20, 30, 40, 50 },
1331 { { 4, 0 }, { 5, 10 } } 1339 { { 4, 0 }, { 5, 10 } }
1332 }, 1340 },
@@ -1339,7 +1347,7 @@ static struct bpf_test tests[] = {
1339 BPF_ALU32_REG(BPF_DIV, R0, R7), 1347 BPF_ALU32_REG(BPF_DIV, R0, R7),
1340 BPF_EXIT_INSN(), 1348 BPF_EXIT_INSN(),
1341 }, 1349 },
1342 SKB_INT, 1350 INTERNAL,
1343 { 10, 20, 30, 40, 50 }, 1351 { 10, 20, 30, 40, 50 },
1344 { { 3, 0 }, { 4, 0 } } 1352 { { 3, 0 }, { 4, 0 } }
1345 }, 1353 },
@@ -1348,7 +1356,7 @@ static struct bpf_test tests[] = {
1348 .u.insns = { 1356 .u.insns = {
1349 BPF_STMT(BPF_LD | BPF_IMM, 1), 1357 BPF_STMT(BPF_LD | BPF_IMM, 1),
1350 }, 1358 },
1351 EXPECTED_FAIL, 1359 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
1352 { }, 1360 { },
1353 { } 1361 { }
1354 }, 1362 },
@@ -1358,7 +1366,7 @@ static struct bpf_test tests[] = {
1358 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0), 1366 BPF_STMT(BPF_ALU | BPF_DIV | BPF_K, 0),
1359 BPF_STMT(BPF_RET | BPF_K, 0) 1367 BPF_STMT(BPF_RET | BPF_K, 0)
1360 }, 1368 },
1361 EXPECTED_FAIL, 1369 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
1362 { }, 1370 { },
1363 { } 1371 { }
1364 }, 1372 },
@@ -1369,7 +1377,7 @@ static struct bpf_test tests[] = {
1369 BPF_STMT(BPF_LDX | BPF_W | BPF_ABS, 0), 1377 BPF_STMT(BPF_LDX | BPF_W | BPF_ABS, 0),
1370 BPF_STMT(BPF_RET | BPF_K, 0) 1378 BPF_STMT(BPF_RET | BPF_K, 0)
1371 }, 1379 },
1372 EXPECTED_FAIL, 1380 CLASSIC | FLAG_EXPECTED_FAIL,
1373 { }, 1381 { },
1374 { } 1382 { }
1375 }, 1383 },
@@ -1379,26 +1387,15 @@ static struct bpf_test tests[] = {
1379 BPF_STMT(BPF_STX, 16), 1387 BPF_STMT(BPF_STX, 16),
1380 BPF_STMT(BPF_RET | BPF_K, 0) 1388 BPF_STMT(BPF_RET | BPF_K, 0)
1381 }, 1389 },
1382 EXPECTED_FAIL, 1390 CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
1383 { }, 1391 { },
1384 { } 1392 { }
1385 }, 1393 },
1386}; 1394};
1387 1395
1388static int get_length(struct sock_filter *fp) 1396static struct net_device dev;
1389{
1390 int len = 0;
1391
1392 while (fp->code != 0 || fp->k != 0) {
1393 fp++;
1394 len++;
1395 }
1396
1397 return len;
1398}
1399 1397
1400struct net_device dev; 1398static struct sk_buff *populate_skb(char *buf, int size)
1401struct sk_buff *populate_skb(char *buf, int size)
1402{ 1399{
1403 struct sk_buff *skb; 1400 struct sk_buff *skb;
1404 1401
@@ -1410,6 +1407,8 @@ struct sk_buff *populate_skb(char *buf, int size)
1410 return NULL; 1407 return NULL;
1411 1408
1412 memcpy(__skb_put(skb, size), buf, size); 1409 memcpy(__skb_put(skb, size), buf, size);
1410
1411 /* Initialize a fake skb with test pattern. */
1413 skb_reset_mac_header(skb); 1412 skb_reset_mac_header(skb);
1414 skb->protocol = htons(ETH_P_IP); 1413 skb->protocol = htons(ETH_P_IP);
1415 skb->pkt_type = SKB_TYPE; 1414 skb->pkt_type = SKB_TYPE;
@@ -1425,43 +1424,149 @@ struct sk_buff *populate_skb(char *buf, int size)
1425 return skb; 1424 return skb;
1426} 1425}
1427 1426
1428static int run_one(struct sk_filter *fp, struct bpf_test *t) 1427static void *generate_test_data(struct bpf_test *test, int sub)
1429{ 1428{
1430 u64 start, finish, res, cnt = 100000; 1429 if (test->aux & FLAG_NO_DATA)
1431 int err_cnt = 0, err, i, j; 1430 return NULL;
1432 u32 ret = 0;
1433 void *data;
1434 1431
1435 for (i = 0; i < MAX_SUBTESTS; i++) { 1432 /* Test case expects an skb, so populate one. Various
1436 if (t->test[i].data_size == 0 && 1433 * subtests generate skbs of different sizes based on
1437 t->test[i].result == 0) 1434 * the same data.
1438 break; 1435 */
1439 if (t->data_type == SKB || 1436 return populate_skb(test->data, test->test[sub].data_size);
1440 t->data_type == SKB_INT) { 1437}
1441 data = populate_skb(t->data, t->test[i].data_size); 1438
1442 if (!data) 1439static void release_test_data(const struct bpf_test *test, void *data)
1443 return -ENOMEM; 1440{
1444 } else { 1441 if (test->aux & FLAG_NO_DATA)
1445 data = NULL; 1442 return;
1443
1444 kfree_skb(data);
1445}
1446
1447static int probe_filter_length(struct sock_filter *fp)
1448{
1449 int len = 0;
1450
1451 while (fp->code != 0 || fp->k != 0) {
1452 fp++;
1453 len++;
1454 }
1455
1456 return len;
1457}
1458
1459static struct sk_filter *generate_filter(int which, int *err)
1460{
1461 struct sk_filter *fp;
1462 struct sock_fprog_kern fprog;
1463 unsigned int flen = probe_filter_length(tests[which].u.insns);
1464 __u8 test_type = tests[which].aux & TEST_TYPE_MASK;
1465
1466 switch (test_type) {
1467 case CLASSIC:
1468 fprog.filter = tests[which].u.insns;
1469 fprog.len = flen;
1470
1471 *err = sk_unattached_filter_create(&fp, &fprog);
1472 if (tests[which].aux & FLAG_EXPECTED_FAIL) {
1473 if (*err == -EINVAL) {
1474 pr_cont("PASS\n");
1475 /* Verifier rejected filter as expected. */
1476 *err = 0;
1477 return NULL;
1478 } else {
1479 pr_cont("UNEXPECTED_PASS\n");
1480 /* Verifier didn't reject the test that's
1481 * bad enough, just return!
1482 */
1483 *err = -EINVAL;
1484 return NULL;
1485 }
1486 }
1487 /* We don't expect to fail. */
1488 if (*err) {
1489 pr_cont("FAIL to attach err=%d len=%d\n",
1490 *err, fprog.len);
1491 return NULL;
1492 }
1493 break;
1494
1495 case INTERNAL:
1496 fp = kzalloc(sk_filter_size(flen), GFP_KERNEL);
1497 if (fp == NULL) {
1498 pr_cont("UNEXPECTED_FAIL no memory left\n");
1499 *err = -ENOMEM;
1500 return NULL;
1446 } 1501 }
1447 1502
1448 start = ktime_to_us(ktime_get()); 1503 fp->len = flen;
1449 for (j = 0; j < cnt; j++) 1504 memcpy(fp->insnsi, tests[which].u.insns_int,
1450 ret = SK_RUN_FILTER(fp, data); 1505 fp->len * sizeof(struct sock_filter_int));
1451 finish = ktime_to_us(ktime_get());
1452 1506
1453 res = (finish - start) * 1000; 1507 sk_filter_select_runtime(fp);
1454 do_div(res, cnt); 1508 break;
1509 }
1455 1510
1456 err = ret != t->test[i].result; 1511 *err = 0;
1457 if (!err) 1512 return fp;
1458 pr_cont("%lld ", res); 1513}
1459 1514
1460 if (t->data_type == SKB || t->data_type == SKB_INT) 1515static void release_filter(struct sk_filter *fp, int which)
1461 kfree_skb(data); 1516{
1517 __u8 test_type = tests[which].aux & TEST_TYPE_MASK;
1462 1518
1463 if (err) { 1519 switch (test_type) {
1464 pr_cont("ret %d != %d ", ret, t->test[i].result); 1520 case CLASSIC:
1521 sk_unattached_filter_destroy(fp);
1522 break;
1523 case INTERNAL:
1524 sk_filter_free(fp);
1525 break;
1526 }
1527}
1528
1529static int __run_one(const struct sk_filter *fp, const void *data,
1530 int runs, u64 *duration)
1531{
1532 u64 start, finish;
1533 int ret, i;
1534
1535 start = ktime_to_us(ktime_get());
1536
1537 for (i = 0; i < runs; i++)
1538 ret = SK_RUN_FILTER(fp, data);
1539
1540 finish = ktime_to_us(ktime_get());
1541
1542 *duration = (finish - start) * 1000ULL;
1543 do_div(*duration, runs);
1544
1545 return ret;
1546}
1547
1548static int run_one(const struct sk_filter *fp, struct bpf_test *test)
1549{
1550 int err_cnt = 0, i, runs = MAX_TESTRUNS;
1551
1552 for (i = 0; i < MAX_SUBTESTS; i++) {
1553 void *data;
1554 u64 duration;
1555 u32 ret;
1556
1557 if (test->test[i].data_size == 0 &&
1558 test->test[i].result == 0)
1559 break;
1560
1561 data = generate_test_data(test, i);
1562 ret = __run_one(fp, data, runs, &duration);
1563 release_test_data(test, data);
1564
1565 if (ret == test->test[i].result) {
1566 pr_cont("%lld ", duration);
1567 } else {
1568 pr_cont("ret %d != %d ", ret,
1569 test->test[i].result);
1465 err_cnt++; 1570 err_cnt++;
1466 } 1571 }
1467 } 1572 }
@@ -1471,65 +1576,37 @@ static int run_one(struct sk_filter *fp, struct bpf_test *t)
1471 1576
1472static __init int test_bpf(void) 1577static __init int test_bpf(void)
1473{ 1578{
1474 struct sk_filter *fp, *fp_ext = NULL; 1579 int i, err_cnt = 0, pass_cnt = 0;
1475 struct sock_fprog_kern fprog;
1476 int err, i, err_cnt = 0;
1477 1580
1478 for (i = 0; i < ARRAY_SIZE(tests); i++) { 1581 for (i = 0; i < ARRAY_SIZE(tests); i++) {
1479 pr_info("#%d %s ", i, tests[i].descr); 1582 struct sk_filter *fp;
1583 int err;
1480 1584
1481 fprog.filter = tests[i].u.insns; 1585 pr_info("#%d %s ", i, tests[i].descr);
1482 fprog.len = get_length(fprog.filter);
1483 1586
1484 if (tests[i].data_type == SKB_INT) { 1587 fp = generate_filter(i, &err);
1485 fp_ext = kzalloc(4096, GFP_KERNEL); 1588 if (fp == NULL) {
1486 if (!fp_ext) 1589 if (err == 0) {
1487 return -ENOMEM; 1590 pass_cnt++;
1488 fp = fp_ext; 1591 continue;
1489 memcpy(fp_ext->insns, tests[i].u.insns_int,
1490 fprog.len * 8);
1491 fp->len = fprog.len;
1492 sk_filter_select_runtime(fp);
1493 } else {
1494 err = sk_unattached_filter_create(&fp, &fprog);
1495 if (tests[i].data_type == EXPECTED_FAIL) {
1496 if (err == -EINVAL) {
1497 pr_cont("PASS\n");
1498 continue;
1499 } else {
1500 pr_cont("UNEXPECTED_PASS\n");
1501 /* verifier didn't reject the test
1502 * that's bad enough, just return
1503 */
1504 return -EINVAL;
1505 }
1506 }
1507 if (err) {
1508 pr_cont("FAIL to attach err=%d len=%d\n",
1509 err, fprog.len);
1510 return err;
1511 } 1592 }
1512 }
1513 1593
1594 return err;
1595 }
1514 err = run_one(fp, &tests[i]); 1596 err = run_one(fp, &tests[i]);
1515 1597 release_filter(fp, i);
1516 if (tests[i].data_type != SKB_INT)
1517 sk_unattached_filter_destroy(fp);
1518 else
1519 sk_filter_free(fp);
1520 1598
1521 if (err) { 1599 if (err) {
1522 pr_cont("FAIL %d\n", err); 1600 pr_cont("FAIL (%d times)\n", err);
1523 err_cnt++; 1601 err_cnt++;
1524 } else { 1602 } else {
1525 pr_cont("PASS\n"); 1603 pr_cont("PASS\n");
1604 pass_cnt++;
1526 } 1605 }
1527 } 1606 }
1528 1607
1529 if (err_cnt) 1608 pr_info("Summary: %d PASSED, %d FAILED\n", pass_cnt, err_cnt);
1530 return -EINVAL; 1609 return err_cnt ? -EINVAL : 0;
1531 else
1532 return 0;
1533} 1610}
1534 1611
1535static int __init test_bpf_init(void) 1612static int __init test_bpf_init(void)
@@ -1543,4 +1620,5 @@ static void __exit test_bpf_exit(void)
1543 1620
1544module_init(test_bpf_init); 1621module_init(test_bpf_init);
1545module_exit(test_bpf_exit); 1622module_exit(test_bpf_exit);
1623
1546MODULE_LICENSE("GPL"); 1624MODULE_LICENSE("GPL");