1 /* 2 * Testsuite for BPF interpreter and BPF JIT compiler 3 * 4 * Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of version 2 of the GNU General Public 8 * License as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 */ 15 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 18 #include <linux/init.h> 19 #include <linux/module.h> 20 #include <linux/filter.h> 21 #include <linux/skbuff.h> 22 #include <linux/netdevice.h> 23 #include <linux/if_vlan.h> 24 25 #define MAX_SUBTESTS 3 26 #define MAX_DATA 128 27 #define MAX_INSNS 512 28 #define MAX_K 0xffffFFFF 29 30 /* define few constants used to init test 'skb' */ 31 #define SKB_TYPE 3 32 #define SKB_MARK 0x1234aaaa 33 #define SKB_HASH 0x1234aaab 34 #define SKB_QUEUE_MAP 123 35 #define SKB_VLAN_TCI 0xffff 36 #define SKB_DEV_IFINDEX 577 37 #define SKB_DEV_TYPE 588 38 39 /* redefine REGs to make tests less verbose */ 40 #define R0 BPF_REG_0 41 #define R1 BPF_REG_1 42 #define R2 BPF_REG_2 43 #define R3 BPF_REG_3 44 #define R4 BPF_REG_4 45 #define R5 BPF_REG_5 46 #define R6 BPF_REG_6 47 #define R7 BPF_REG_7 48 #define R8 BPF_REG_8 49 #define R9 BPF_REG_9 50 #define R10 BPF_REG_10 51 52 struct bpf_test { 53 const char *descr; 54 union { 55 struct sock_filter insns[MAX_INSNS]; 56 struct sock_filter_int insns_int[MAX_INSNS]; 57 }; 58 enum { 59 NO_DATA, 60 EXPECTED_FAIL, 61 SKB, 62 SKB_INT 63 } data_type; 64 __u8 data[MAX_DATA]; 65 struct { 66 int data_size; 67 __u32 result; 68 } test[MAX_SUBTESTS]; 69 }; 70 71 static struct bpf_test tests[] = { 72 { 73 "TAX", 74 .insns = { 75 BPF_STMT(BPF_LD | BPF_IMM, 1), 76 BPF_STMT(BPF_MISC | BPF_TAX, 0), 77 BPF_STMT(BPF_LD | BPF_IMM, 2), 78 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 79 BPF_STMT(BPF_ALU | BPF_NEG, 0), /* A == -3 */ 80 BPF_STMT(BPF_MISC | BPF_TAX, 0), 81 BPF_STMT(BPF_LD | BPF_LEN, 0), 82 BPF_STMT(BPF_ALU | BPF_ADD | BPF_X, 0), 83 BPF_STMT(BPF_MISC | BPF_TAX, 0), /* X == len - 3 */ 84 BPF_STMT(BPF_LD | BPF_B | BPF_IND, 1), 85 BPF_STMT(BPF_RET | BPF_A, 0) 86 }, 87 SKB, 88 { 10, 20, 30, 40, 50 }, 89 { { 2, 10 }, { 3, 20 }, { 4, 30 } }, 90 }, 91 { 92 "tcpdump port 22", 93 .insns = { 94 { 0x28, 0, 0, 0x0000000c }, 95 { 0x15, 0, 8, 0x000086dd }, 96 { 0x30, 0, 0, 0x00000014 }, 97 { 0x15, 2, 0, 0x00000084 }, 98 { 0x15, 1, 0, 0x00000006 }, 99 { 0x15, 0, 17, 0x00000011 }, 100 { 0x28, 0, 0, 0x00000036 }, 101 { 0x15, 14, 0, 0x00000016 }, 102 { 0x28, 0, 0, 0x00000038 }, 103 { 0x15, 12, 13, 0x00000016 }, 104 { 0x15, 0, 12, 0x00000800 }, 105 { 0x30, 0, 0, 0x00000017 }, 106 { 0x15, 2, 0, 0x00000084 }, 107 { 0x15, 1, 0, 0x00000006 }, 108 { 0x15, 0, 8, 0x00000011 }, 109 { 0x28, 0, 0, 0x00000014 }, 110 { 0x45, 6, 0, 0x00001fff }, 111 { 0xb1, 0, 0, 0x0000000e }, 112 { 0x48, 0, 0, 0x0000000e }, 113 { 0x15, 2, 0, 0x00000016 }, 114 { 0x48, 0, 0, 0x00000010 }, 115 { 0x15, 0, 1, 0x00000016 }, 116 { 0x06, 0, 0, 0x0000ffff }, 117 { 0x06, 0, 0, 0x00000000 }, 118 }, 119 SKB, 120 /* 3c:07:54:43:e5:76 > 10:bf:48:d6:43:d6, ethertype IPv4(0x0800) 121 * length 114: 10.1.1.149.49700 > 10.1.2.10.22: Flags [P.], 122 * seq 1305692979:1305693027, ack 3650467037, win 65535, 123 * options [nop,nop,TS val 2502645400 ecr 3971138], length 48 124 */ 125 { 0x10, 0xbf, 0x48, 0xd6, 0x43, 0xd6, 126 0x3c, 0x07, 0x54, 0x43, 0xe5, 0x76, 127 0x08, 0x00, 128 0x45, 0x10, 0x00, 0x64, 0x75, 0xb5, 129 0x40, 0x00, 0x40, 0x06, 0xad, 0x2e, /* IP header */ 130 0x0a, 0x01, 0x01, 0x95, /* ip src */ 131 0x0a, 0x01, 0x02, 0x0a, /* ip dst */ 132 0xc2, 0x24, 133 0x00, 0x16 /* dst port */ }, 134 { { 10, 0 }, { 30, 0 }, { 100, 65535 } }, 135 }, 136 { 137 "INT: DIV + ABS", 138 .insns_int = { 139 BPF_ALU64_REG(BPF_MOV, R6, R1), 140 BPF_LD_ABS(BPF_B, 3), 141 BPF_ALU64_IMM(BPF_MOV, R2, 2), 142 BPF_ALU32_REG(BPF_DIV, R0, R2), 143 BPF_ALU64_REG(BPF_MOV, R8, R0), 144 BPF_LD_ABS(BPF_B, 4), 145 BPF_ALU64_REG(BPF_ADD, R8, R0), 146 BPF_LD_IND(BPF_B, R8, -70), 147 BPF_EXIT_INSN(), 148 }, 149 SKB_INT, 150 { 10, 20, 30, 40, 50 }, 151 { { 4, 0 }, { 5, 10 } } 152 }, 153 { 154 "check: missing ret", 155 .insns = { 156 BPF_STMT(BPF_LD | BPF_IMM, 1), 157 }, 158 EXPECTED_FAIL, 159 { }, 160 { } 161 }, 162 }; 163 164 static int get_length(struct sock_filter *fp) 165 { 166 int len = 0; 167 168 while (fp->code != 0 || fp->k != 0) { 169 fp++; 170 len++; 171 } 172 173 return len; 174 } 175 176 struct net_device dev; 177 struct sk_buff *populate_skb(char *buf, int size) 178 { 179 struct sk_buff *skb; 180 181 if (size >= MAX_DATA) 182 return NULL; 183 184 skb = alloc_skb(MAX_DATA, GFP_KERNEL); 185 if (!skb) 186 return NULL; 187 188 memcpy(__skb_put(skb, size), buf, size); 189 skb_reset_mac_header(skb); 190 skb->protocol = htons(ETH_P_IP); 191 skb->pkt_type = SKB_TYPE; 192 skb->mark = SKB_MARK; 193 skb->hash = SKB_HASH; 194 skb->queue_mapping = SKB_QUEUE_MAP; 195 skb->vlan_tci = SKB_VLAN_TCI; 196 skb->dev = &dev; 197 skb->dev->ifindex = SKB_DEV_IFINDEX; 198 skb->dev->type = SKB_DEV_TYPE; 199 skb_set_network_header(skb, min(size, ETH_HLEN)); 200 201 return skb; 202 } 203 204 static int run_one(struct sk_filter *fp, struct bpf_test *t) 205 { 206 u64 start, finish, res, cnt = 100000; 207 int err_cnt = 0, err, i, j; 208 u32 ret = 0; 209 void *data; 210 211 for (i = 0; i < MAX_SUBTESTS; i++) { 212 if (t->test[i].data_size == 0 && 213 t->test[i].result == 0) 214 break; 215 if (t->data_type == SKB || 216 t->data_type == SKB_INT) { 217 data = populate_skb(t->data, t->test[i].data_size); 218 if (!data) 219 return -ENOMEM; 220 } else { 221 data = NULL; 222 } 223 224 start = ktime_to_us(ktime_get()); 225 for (j = 0; j < cnt; j++) 226 ret = SK_RUN_FILTER(fp, data); 227 finish = ktime_to_us(ktime_get()); 228 229 res = (finish - start) * 1000; 230 do_div(res, cnt); 231 232 err = ret != t->test[i].result; 233 if (!err) 234 pr_cont("%lld ", res); 235 236 if (t->data_type == SKB || t->data_type == SKB_INT) 237 kfree_skb(data); 238 239 if (err) { 240 pr_cont("ret %d != %d ", ret, t->test[i].result); 241 err_cnt++; 242 } 243 } 244 245 return err_cnt; 246 } 247 248 static __init int test_bpf(void) 249 { 250 struct sk_filter *fp, *fp_ext = NULL; 251 struct sock_fprog fprog; 252 int err, i, err_cnt = 0; 253 254 for (i = 0; i < ARRAY_SIZE(tests); i++) { 255 pr_info("#%d %s ", i, tests[i].descr); 256 257 fprog.filter = tests[i].insns; 258 fprog.len = get_length(fprog.filter); 259 260 if (tests[i].data_type == SKB_INT) { 261 fp_ext = kzalloc(4096, GFP_KERNEL); 262 if (!fp_ext) 263 return -ENOMEM; 264 fp = fp_ext; 265 memcpy(fp_ext->insns, tests[i].insns_int, 266 fprog.len * 8); 267 fp->len = fprog.len; 268 fp->bpf_func = sk_run_filter_int_skb; 269 } else { 270 err = sk_unattached_filter_create(&fp, &fprog); 271 if (tests[i].data_type == EXPECTED_FAIL) { 272 if (err == -EINVAL) { 273 pr_cont("PASS\n"); 274 continue; 275 } else { 276 pr_cont("UNEXPECTED_PASS\n"); 277 /* verifier didn't reject the test 278 * that's bad enough, just return 279 */ 280 return -EINVAL; 281 } 282 } 283 if (err) { 284 pr_cont("FAIL to attach err=%d len=%d\n", 285 err, fprog.len); 286 return err; 287 } 288 } 289 290 err = run_one(fp, &tests[i]); 291 292 if (tests[i].data_type != SKB_INT) 293 sk_unattached_filter_destroy(fp); 294 else 295 kfree(fp); 296 297 if (err) { 298 pr_cont("FAIL %d\n", err); 299 err_cnt++; 300 } else { 301 pr_cont("PASS\n"); 302 } 303 } 304 305 if (err_cnt) 306 return -EINVAL; 307 else 308 return 0; 309 } 310 311 static int __init test_bpf_init(void) 312 { 313 return test_bpf(); 314 } 315 316 static void __exit test_bpf_exit(void) 317 { 318 } 319 320 module_init(test_bpf_init); 321 module_exit(test_bpf_exit); 322 MODULE_LICENSE("GPL"); 323