aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
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");