1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 2a9de470cSBruce Richardson * Copyright(c) 2018 Intel Corporation 3a9de470cSBruce Richardson */ 4a9de470cSBruce Richardson 5a9de470cSBruce Richardson #include <stdio.h> 6a9de470cSBruce Richardson #include <string.h> 7a9de470cSBruce Richardson #include <stdint.h> 8a9de470cSBruce Richardson #include <inttypes.h> 9a9de470cSBruce Richardson 10a9de470cSBruce Richardson #include <rte_memory.h> 11a9de470cSBruce Richardson #include <rte_debug.h> 12a9de470cSBruce Richardson #include <rte_hexdump.h> 132eccf6afSStephen Hemminger #include <rte_malloc.h> 14a9de470cSBruce Richardson #include <rte_random.h> 15a9de470cSBruce Richardson #include <rte_byteorder.h> 16a9de470cSBruce Richardson #include <rte_errno.h> 173c60274cSJie Zhou #include "test.h" 183c60274cSJie Zhou 193c60274cSJie Zhou #if !defined(RTE_LIB_BPF) 203c60274cSJie Zhou 213c60274cSJie Zhou static int 223c60274cSJie Zhou test_bpf(void) 233c60274cSJie Zhou { 243c60274cSJie Zhou printf("BPF not supported, skipping test\n"); 253c60274cSJie Zhou return TEST_SKIPPED; 263c60274cSJie Zhou } 273c60274cSJie Zhou 283c60274cSJie Zhou #else 293c60274cSJie Zhou 30a9de470cSBruce Richardson #include <rte_bpf.h> 31cddd8795SHarman Kalra #include <rte_ether.h> 32cddd8795SHarman Kalra #include <rte_ip.h> 33a9de470cSBruce Richardson 34a9de470cSBruce Richardson 35a9de470cSBruce Richardson /* 36a9de470cSBruce Richardson * Basic functional tests for librte_bpf. 37a9de470cSBruce Richardson * The main procedure - load eBPF program, execute it and 387be78d02SJosh Soref * compare results with expected values. 39a9de470cSBruce Richardson */ 40a9de470cSBruce Richardson 41a9de470cSBruce Richardson struct dummy_offset { 42b6a7e685STyler Retzlaff RTE_ATOMIC(uint64_t) u64; 43b6a7e685STyler Retzlaff RTE_ATOMIC(uint32_t) u32; 44a9de470cSBruce Richardson uint16_t u16; 45a9de470cSBruce Richardson uint8_t u8; 46a9de470cSBruce Richardson }; 47a9de470cSBruce Richardson 48a9de470cSBruce Richardson struct dummy_vect8 { 49a9de470cSBruce Richardson struct dummy_offset in[8]; 50a9de470cSBruce Richardson struct dummy_offset out[8]; 51a9de470cSBruce Richardson }; 52a9de470cSBruce Richardson 53cddd8795SHarman Kalra struct dummy_net { 54cddd8795SHarman Kalra struct rte_ether_hdr eth_hdr; 55cddd8795SHarman Kalra struct rte_vlan_hdr vlan_hdr; 56cddd8795SHarman Kalra struct rte_ipv4_hdr ip_hdr; 57cddd8795SHarman Kalra }; 58cddd8795SHarman Kalra 59b901d928SKonstantin Ananyev #define DUMMY_MBUF_NUM 2 60b901d928SKonstantin Ananyev 61b901d928SKonstantin Ananyev /* first mbuf in the packet, should always be at offset 0 */ 62b901d928SKonstantin Ananyev struct dummy_mbuf { 63b901d928SKonstantin Ananyev struct rte_mbuf mb[DUMMY_MBUF_NUM]; 64b901d928SKonstantin Ananyev uint8_t buf[DUMMY_MBUF_NUM][RTE_MBUF_DEFAULT_BUF_SIZE]; 65b901d928SKonstantin Ananyev }; 66b901d928SKonstantin Ananyev 67a9de470cSBruce Richardson #define TEST_FILL_1 0xDEADBEEF 68a9de470cSBruce Richardson 69a9de470cSBruce Richardson #define TEST_MUL_1 21 70a9de470cSBruce Richardson #define TEST_MUL_2 -100 71a9de470cSBruce Richardson 72a9de470cSBruce Richardson #define TEST_SHIFT_1 15 73a9de470cSBruce Richardson #define TEST_SHIFT_2 33 74a9de470cSBruce Richardson 753ac2dffaSKonstantin Ananyev #define TEST_SHIFT32_MASK (CHAR_BIT * sizeof(uint32_t) - 1) 763ac2dffaSKonstantin Ananyev #define TEST_SHIFT64_MASK (CHAR_BIT * sizeof(uint64_t) - 1) 773ac2dffaSKonstantin Ananyev 78a9de470cSBruce Richardson #define TEST_JCC_1 0 79a9de470cSBruce Richardson #define TEST_JCC_2 -123 80a9de470cSBruce Richardson #define TEST_JCC_3 5678 81a9de470cSBruce Richardson #define TEST_JCC_4 TEST_FILL_1 82a9de470cSBruce Richardson 83a9de470cSBruce Richardson #define TEST_IMM_1 UINT64_MAX 84a9de470cSBruce Richardson #define TEST_IMM_2 ((uint64_t)INT64_MIN) 85a9de470cSBruce Richardson #define TEST_IMM_3 ((uint64_t)INT64_MAX + INT32_MAX) 86a9de470cSBruce Richardson #define TEST_IMM_4 ((uint64_t)UINT32_MAX) 87a9de470cSBruce Richardson #define TEST_IMM_5 ((uint64_t)UINT32_MAX + 1) 88a9de470cSBruce Richardson 89cddd8795SHarman Kalra #define TEST_MEMFROB 0x2a2a2a2a 90cddd8795SHarman Kalra 91cddd8795SHarman Kalra #define STRING_GEEK 0x6B656567 92cddd8795SHarman Kalra #define STRING_WEEK 0x6B656577 93cddd8795SHarman Kalra 94cddd8795SHarman Kalra #define TEST_NETMASK 0xffffff00 95cddd8795SHarman Kalra #define TEST_SUBNET 0xaca80200 96cddd8795SHarman Kalra 97cddd8795SHarman Kalra uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF }; 98cddd8795SHarman Kalra uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA }; 99cddd8795SHarman Kalra 100cddd8795SHarman Kalra uint32_t ip_src_addr = (172U << 24) | (168U << 16) | (2 << 8) | 1; 101cddd8795SHarman Kalra uint32_t ip_dst_addr = (172U << 24) | (168U << 16) | (2 << 8) | 2; 102cddd8795SHarman Kalra 103a9de470cSBruce Richardson struct bpf_test { 104a9de470cSBruce Richardson const char *name; 105a9de470cSBruce Richardson size_t arg_sz; 106a9de470cSBruce Richardson struct rte_bpf_prm prm; 107a9de470cSBruce Richardson void (*prepare)(void *); 108a9de470cSBruce Richardson int (*check_result)(uint64_t, const void *); 109a9de470cSBruce Richardson uint32_t allow_fail; 110a9de470cSBruce Richardson }; 111a9de470cSBruce Richardson 112a9de470cSBruce Richardson /* 113a9de470cSBruce Richardson * Compare return value and result data with expected ones. 114a9de470cSBruce Richardson * Report a failure if they don't match. 115a9de470cSBruce Richardson */ 116a9de470cSBruce Richardson static int 117a9de470cSBruce Richardson cmp_res(const char *func, uint64_t exp_rc, uint64_t ret_rc, 118a9de470cSBruce Richardson const void *exp_res, const void *ret_res, size_t res_sz) 119a9de470cSBruce Richardson { 120a9de470cSBruce Richardson int32_t ret; 121a9de470cSBruce Richardson 122a9de470cSBruce Richardson ret = 0; 123a9de470cSBruce Richardson if (exp_rc != ret_rc) { 124a9de470cSBruce Richardson printf("%s@%d: invalid return value, expected: 0x%" PRIx64 125a9de470cSBruce Richardson ",result: 0x%" PRIx64 "\n", 126a9de470cSBruce Richardson func, __LINE__, exp_rc, ret_rc); 127a9de470cSBruce Richardson ret |= -1; 128a9de470cSBruce Richardson } 129a9de470cSBruce Richardson 130a9de470cSBruce Richardson if (memcmp(exp_res, ret_res, res_sz) != 0) { 131a9de470cSBruce Richardson printf("%s: invalid value\n", func); 132a9de470cSBruce Richardson rte_memdump(stdout, "expected", exp_res, res_sz); 133a9de470cSBruce Richardson rte_memdump(stdout, "result", ret_res, res_sz); 134a9de470cSBruce Richardson ret |= -1; 135a9de470cSBruce Richardson } 136a9de470cSBruce Richardson 137a9de470cSBruce Richardson return ret; 138a9de470cSBruce Richardson } 139a9de470cSBruce Richardson 140a9de470cSBruce Richardson /* store immediate test-cases */ 141a9de470cSBruce Richardson static const struct ebpf_insn test_store1_prog[] = { 142a9de470cSBruce Richardson { 143a9de470cSBruce Richardson .code = (BPF_ST | BPF_MEM | BPF_B), 144a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 145a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u8), 146a9de470cSBruce Richardson .imm = TEST_FILL_1, 147a9de470cSBruce Richardson }, 148a9de470cSBruce Richardson { 149a9de470cSBruce Richardson .code = (BPF_ST | BPF_MEM | BPF_H), 150a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 151a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u16), 152a9de470cSBruce Richardson .imm = TEST_FILL_1, 153a9de470cSBruce Richardson }, 154a9de470cSBruce Richardson { 155a9de470cSBruce Richardson .code = (BPF_ST | BPF_MEM | BPF_W), 156a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 157a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 158a9de470cSBruce Richardson .imm = TEST_FILL_1, 159a9de470cSBruce Richardson }, 160a9de470cSBruce Richardson { 161a9de470cSBruce Richardson .code = (BPF_ST | BPF_MEM | EBPF_DW), 162a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 163a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 164a9de470cSBruce Richardson .imm = TEST_FILL_1, 165a9de470cSBruce Richardson }, 166a9de470cSBruce Richardson /* return 1 */ 167a9de470cSBruce Richardson { 168a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 169a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 170a9de470cSBruce Richardson .imm = 1, 171a9de470cSBruce Richardson }, 172a9de470cSBruce Richardson { 173a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 174a9de470cSBruce Richardson }, 175a9de470cSBruce Richardson }; 176a9de470cSBruce Richardson 177a9de470cSBruce Richardson static void 178a9de470cSBruce Richardson test_store1_prepare(void *arg) 179a9de470cSBruce Richardson { 180a9de470cSBruce Richardson struct dummy_offset *df; 181a9de470cSBruce Richardson 182a9de470cSBruce Richardson df = arg; 183a9de470cSBruce Richardson memset(df, 0, sizeof(*df)); 184a9de470cSBruce Richardson } 185a9de470cSBruce Richardson 186a9de470cSBruce Richardson static int 187a9de470cSBruce Richardson test_store1_check(uint64_t rc, const void *arg) 188a9de470cSBruce Richardson { 189a9de470cSBruce Richardson const struct dummy_offset *dft; 190a9de470cSBruce Richardson struct dummy_offset dfe; 191a9de470cSBruce Richardson 192a9de470cSBruce Richardson dft = arg; 193a9de470cSBruce Richardson 194a9de470cSBruce Richardson memset(&dfe, 0, sizeof(dfe)); 195a9de470cSBruce Richardson dfe.u64 = (int32_t)TEST_FILL_1; 196a9de470cSBruce Richardson dfe.u32 = dfe.u64; 197a9de470cSBruce Richardson dfe.u16 = dfe.u64; 198a9de470cSBruce Richardson dfe.u8 = dfe.u64; 199a9de470cSBruce Richardson 200a9de470cSBruce Richardson return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); 201a9de470cSBruce Richardson } 202a9de470cSBruce Richardson 203a9de470cSBruce Richardson /* store register test-cases */ 204a9de470cSBruce Richardson static const struct ebpf_insn test_store2_prog[] = { 205a9de470cSBruce Richardson 206a9de470cSBruce Richardson { 207a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 208a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 209a9de470cSBruce Richardson .imm = TEST_FILL_1, 210a9de470cSBruce Richardson }, 211a9de470cSBruce Richardson { 212a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | BPF_B), 213a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 214a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 215a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u8), 216a9de470cSBruce Richardson }, 217a9de470cSBruce Richardson { 218a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | BPF_H), 219a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 220a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 221a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u16), 222a9de470cSBruce Richardson }, 223a9de470cSBruce Richardson { 224a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | BPF_W), 225a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 226a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 227a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 228a9de470cSBruce Richardson }, 229a9de470cSBruce Richardson { 230a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 231a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 232a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 233a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 234a9de470cSBruce Richardson }, 235a9de470cSBruce Richardson /* return 1 */ 236a9de470cSBruce Richardson { 237a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 238a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 239a9de470cSBruce Richardson .imm = 1, 240a9de470cSBruce Richardson }, 241a9de470cSBruce Richardson { 242a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 243a9de470cSBruce Richardson }, 244a9de470cSBruce Richardson }; 245a9de470cSBruce Richardson 246a9de470cSBruce Richardson /* load test-cases */ 247a9de470cSBruce Richardson static const struct ebpf_insn test_load1_prog[] = { 248a9de470cSBruce Richardson 249a9de470cSBruce Richardson { 250a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_B), 251a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 252a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 253a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u8), 254a9de470cSBruce Richardson }, 255a9de470cSBruce Richardson { 256a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_H), 257a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 258a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 259a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u16), 260a9de470cSBruce Richardson }, 261a9de470cSBruce Richardson { 262a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 263a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 264a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 265a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 266a9de470cSBruce Richardson }, 267a9de470cSBruce Richardson { 268a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 269a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 270a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 271a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 272a9de470cSBruce Richardson }, 273a9de470cSBruce Richardson /* return sum */ 274a9de470cSBruce Richardson { 275a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 276a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 277a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 278a9de470cSBruce Richardson }, 279a9de470cSBruce Richardson { 280a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 281a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 282a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 283a9de470cSBruce Richardson }, 284a9de470cSBruce Richardson { 285a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 286a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 287a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 288a9de470cSBruce Richardson }, 289a9de470cSBruce Richardson { 290a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 291a9de470cSBruce Richardson }, 292a9de470cSBruce Richardson }; 293a9de470cSBruce Richardson 294a9de470cSBruce Richardson static void 295a9de470cSBruce Richardson test_load1_prepare(void *arg) 296a9de470cSBruce Richardson { 297a9de470cSBruce Richardson struct dummy_offset *df; 298a9de470cSBruce Richardson 299a9de470cSBruce Richardson df = arg; 300a9de470cSBruce Richardson 301a9de470cSBruce Richardson memset(df, 0, sizeof(*df)); 302a9de470cSBruce Richardson df->u64 = (int32_t)TEST_FILL_1; 303a9de470cSBruce Richardson df->u32 = df->u64; 304a9de470cSBruce Richardson df->u16 = df->u64; 305a9de470cSBruce Richardson df->u8 = df->u64; 306a9de470cSBruce Richardson } 307a9de470cSBruce Richardson 308a9de470cSBruce Richardson static int 309a9de470cSBruce Richardson test_load1_check(uint64_t rc, const void *arg) 310a9de470cSBruce Richardson { 311a9de470cSBruce Richardson uint64_t v; 312a9de470cSBruce Richardson const struct dummy_offset *dft; 313a9de470cSBruce Richardson 314a9de470cSBruce Richardson dft = arg; 315a9de470cSBruce Richardson v = dft->u64; 316a9de470cSBruce Richardson v += dft->u32; 317a9de470cSBruce Richardson v += dft->u16; 318a9de470cSBruce Richardson v += dft->u8; 319a9de470cSBruce Richardson 320a9de470cSBruce Richardson return cmp_res(__func__, v, rc, dft, dft, sizeof(*dft)); 321a9de470cSBruce Richardson } 322a9de470cSBruce Richardson 323a9de470cSBruce Richardson /* load immediate test-cases */ 324a9de470cSBruce Richardson static const struct ebpf_insn test_ldimm1_prog[] = { 325a9de470cSBruce Richardson 326a9de470cSBruce Richardson { 327a9de470cSBruce Richardson .code = (BPF_LD | BPF_IMM | EBPF_DW), 328a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 329a9de470cSBruce Richardson .imm = (uint32_t)TEST_IMM_1, 330a9de470cSBruce Richardson }, 331a9de470cSBruce Richardson { 332a9de470cSBruce Richardson .imm = TEST_IMM_1 >> 32, 333a9de470cSBruce Richardson }, 334a9de470cSBruce Richardson { 335a9de470cSBruce Richardson .code = (BPF_LD | BPF_IMM | EBPF_DW), 336a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 337a9de470cSBruce Richardson .imm = (uint32_t)TEST_IMM_2, 338a9de470cSBruce Richardson }, 339a9de470cSBruce Richardson { 340a9de470cSBruce Richardson .imm = TEST_IMM_2 >> 32, 341a9de470cSBruce Richardson }, 342a9de470cSBruce Richardson { 343a9de470cSBruce Richardson .code = (BPF_LD | BPF_IMM | EBPF_DW), 344a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 345a9de470cSBruce Richardson .imm = (uint32_t)TEST_IMM_3, 346a9de470cSBruce Richardson }, 347a9de470cSBruce Richardson { 348a9de470cSBruce Richardson .imm = TEST_IMM_3 >> 32, 349a9de470cSBruce Richardson }, 350a9de470cSBruce Richardson { 351a9de470cSBruce Richardson .code = (BPF_LD | BPF_IMM | EBPF_DW), 352a9de470cSBruce Richardson .dst_reg = EBPF_REG_7, 353a9de470cSBruce Richardson .imm = (uint32_t)TEST_IMM_4, 354a9de470cSBruce Richardson }, 355a9de470cSBruce Richardson { 356a9de470cSBruce Richardson .imm = TEST_IMM_4 >> 32, 357a9de470cSBruce Richardson }, 358a9de470cSBruce Richardson { 359a9de470cSBruce Richardson .code = (BPF_LD | BPF_IMM | EBPF_DW), 360a9de470cSBruce Richardson .dst_reg = EBPF_REG_9, 361a9de470cSBruce Richardson .imm = (uint32_t)TEST_IMM_5, 362a9de470cSBruce Richardson }, 363a9de470cSBruce Richardson { 364a9de470cSBruce Richardson .imm = TEST_IMM_5 >> 32, 365a9de470cSBruce Richardson }, 366a9de470cSBruce Richardson /* return sum */ 367a9de470cSBruce Richardson { 368a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 369a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 370a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 371a9de470cSBruce Richardson }, 372a9de470cSBruce Richardson { 373a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 374a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 375a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 376a9de470cSBruce Richardson }, 377a9de470cSBruce Richardson { 378a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 379a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 380a9de470cSBruce Richardson .src_reg = EBPF_REG_7, 381a9de470cSBruce Richardson }, 382a9de470cSBruce Richardson { 383a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 384a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 385a9de470cSBruce Richardson .src_reg = EBPF_REG_9, 386a9de470cSBruce Richardson }, 387a9de470cSBruce Richardson { 388a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 389a9de470cSBruce Richardson }, 390a9de470cSBruce Richardson }; 391a9de470cSBruce Richardson 392a9de470cSBruce Richardson static int 393a9de470cSBruce Richardson test_ldimm1_check(uint64_t rc, const void *arg) 394a9de470cSBruce Richardson { 395a9de470cSBruce Richardson uint64_t v1, v2; 396a9de470cSBruce Richardson 397a9de470cSBruce Richardson v1 = TEST_IMM_1; 398a9de470cSBruce Richardson v2 = TEST_IMM_2; 399a9de470cSBruce Richardson v1 += v2; 400a9de470cSBruce Richardson v2 = TEST_IMM_3; 401a9de470cSBruce Richardson v1 += v2; 402a9de470cSBruce Richardson v2 = TEST_IMM_4; 403a9de470cSBruce Richardson v1 += v2; 404a9de470cSBruce Richardson v2 = TEST_IMM_5; 405a9de470cSBruce Richardson v1 += v2; 406a9de470cSBruce Richardson 407a9de470cSBruce Richardson return cmp_res(__func__, v1, rc, arg, arg, 0); 408a9de470cSBruce Richardson } 409a9de470cSBruce Richardson 410a9de470cSBruce Richardson 411a9de470cSBruce Richardson /* alu mul test-cases */ 412a9de470cSBruce Richardson static const struct ebpf_insn test_mul1_prog[] = { 413a9de470cSBruce Richardson 414a9de470cSBruce Richardson { 415a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 416a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 417a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 418a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 419a9de470cSBruce Richardson }, 420a9de470cSBruce Richardson { 421a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 422a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 423a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 424a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 425a9de470cSBruce Richardson }, 426a9de470cSBruce Richardson { 427a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 428a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 429a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 430a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[2].u32), 431a9de470cSBruce Richardson }, 432a9de470cSBruce Richardson { 433a9de470cSBruce Richardson .code = (BPF_ALU | BPF_MUL | BPF_K), 434a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 435a9de470cSBruce Richardson .imm = TEST_MUL_1, 436a9de470cSBruce Richardson }, 437a9de470cSBruce Richardson { 438a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_MUL | BPF_K), 439a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 440a9de470cSBruce Richardson .imm = TEST_MUL_2, 441a9de470cSBruce Richardson }, 442a9de470cSBruce Richardson { 443a9de470cSBruce Richardson .code = (BPF_ALU | BPF_MUL | BPF_X), 444a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 445a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 446a9de470cSBruce Richardson }, 447a9de470cSBruce Richardson { 448a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_MUL | BPF_X), 449a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 450a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 451a9de470cSBruce Richardson }, 452a9de470cSBruce Richardson { 453a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 454a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 455a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 456a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[0].u64), 457a9de470cSBruce Richardson }, 458a9de470cSBruce Richardson { 459a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 460a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 461a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 462a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[1].u64), 463a9de470cSBruce Richardson }, 464a9de470cSBruce Richardson { 465a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 466a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 467a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 468a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[2].u64), 469a9de470cSBruce Richardson }, 470a9de470cSBruce Richardson /* return 1 */ 471a9de470cSBruce Richardson { 472a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 473a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 474a9de470cSBruce Richardson .imm = 1, 475a9de470cSBruce Richardson }, 476a9de470cSBruce Richardson { 477a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 478a9de470cSBruce Richardson }, 479a9de470cSBruce Richardson }; 480a9de470cSBruce Richardson 481a9de470cSBruce Richardson static void 482a9de470cSBruce Richardson test_mul1_prepare(void *arg) 483a9de470cSBruce Richardson { 484a9de470cSBruce Richardson struct dummy_vect8 *dv; 485a9de470cSBruce Richardson uint64_t v; 486a9de470cSBruce Richardson 487a9de470cSBruce Richardson dv = arg; 488a9de470cSBruce Richardson 489a9de470cSBruce Richardson v = rte_rand(); 490a9de470cSBruce Richardson 491a9de470cSBruce Richardson memset(dv, 0, sizeof(*dv)); 492a9de470cSBruce Richardson dv->in[0].u32 = v; 493a9de470cSBruce Richardson dv->in[1].u64 = v << 12 | v >> 6; 494a9de470cSBruce Richardson dv->in[2].u32 = -v; 495a9de470cSBruce Richardson } 496a9de470cSBruce Richardson 497a9de470cSBruce Richardson static int 498a9de470cSBruce Richardson test_mul1_check(uint64_t rc, const void *arg) 499a9de470cSBruce Richardson { 500a9de470cSBruce Richardson uint64_t r2, r3, r4; 501a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 502a9de470cSBruce Richardson struct dummy_vect8 dve; 503a9de470cSBruce Richardson 504a9de470cSBruce Richardson dvt = arg; 505a9de470cSBruce Richardson memset(&dve, 0, sizeof(dve)); 506a9de470cSBruce Richardson 507a9de470cSBruce Richardson r2 = dvt->in[0].u32; 508a9de470cSBruce Richardson r3 = dvt->in[1].u64; 509a9de470cSBruce Richardson r4 = dvt->in[2].u32; 510a9de470cSBruce Richardson 511a9de470cSBruce Richardson r2 = (uint32_t)r2 * TEST_MUL_1; 512a9de470cSBruce Richardson r3 *= TEST_MUL_2; 513a9de470cSBruce Richardson r4 = (uint32_t)(r4 * r2); 514a9de470cSBruce Richardson r4 *= r3; 515a9de470cSBruce Richardson 516a9de470cSBruce Richardson dve.out[0].u64 = r2; 517a9de470cSBruce Richardson dve.out[1].u64 = r3; 518a9de470cSBruce Richardson dve.out[2].u64 = r4; 519a9de470cSBruce Richardson 520a9de470cSBruce Richardson return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); 521a9de470cSBruce Richardson } 522a9de470cSBruce Richardson 523a9de470cSBruce Richardson /* alu shift test-cases */ 524a9de470cSBruce Richardson static const struct ebpf_insn test_shift1_prog[] = { 525a9de470cSBruce Richardson 526a9de470cSBruce Richardson { 527a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 528a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 529a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 530a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 531a9de470cSBruce Richardson }, 532a9de470cSBruce Richardson { 533a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 534a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 535a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 536a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 537a9de470cSBruce Richardson }, 538a9de470cSBruce Richardson { 539a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 540a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 541a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 542a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[2].u32), 543a9de470cSBruce Richardson }, 544a9de470cSBruce Richardson { 545a9de470cSBruce Richardson .code = (BPF_ALU | BPF_LSH | BPF_K), 546a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 547a9de470cSBruce Richardson .imm = TEST_SHIFT_1, 548a9de470cSBruce Richardson }, 549a9de470cSBruce Richardson { 550a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_ARSH | BPF_K), 551a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 552a9de470cSBruce Richardson .imm = TEST_SHIFT_2, 553a9de470cSBruce Richardson }, 554a9de470cSBruce Richardson { 555a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 556a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 557a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 558a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[0].u64), 559a9de470cSBruce Richardson }, 560a9de470cSBruce Richardson { 561a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 562a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 563a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 564a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[1].u64), 565a9de470cSBruce Richardson }, 566a9de470cSBruce Richardson { 5673ac2dffaSKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 5683ac2dffaSKonstantin Ananyev .dst_reg = EBPF_REG_4, 5693ac2dffaSKonstantin Ananyev .imm = TEST_SHIFT64_MASK, 570a9de470cSBruce Richardson }, 571a9de470cSBruce Richardson { 572a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_LSH | BPF_X), 573a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 574a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 575a9de470cSBruce Richardson }, 576a9de470cSBruce Richardson { 5773ac2dffaSKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 5783ac2dffaSKonstantin Ananyev .dst_reg = EBPF_REG_4, 5793ac2dffaSKonstantin Ananyev .imm = TEST_SHIFT32_MASK, 5803ac2dffaSKonstantin Ananyev }, 5813ac2dffaSKonstantin Ananyev { 5823ac2dffaSKonstantin Ananyev .code = (BPF_ALU | BPF_RSH | BPF_X), 5833ac2dffaSKonstantin Ananyev .dst_reg = EBPF_REG_2, 5843ac2dffaSKonstantin Ananyev .src_reg = EBPF_REG_4, 5853ac2dffaSKonstantin Ananyev }, 5863ac2dffaSKonstantin Ananyev { 587a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 588a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 589a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 590a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[2].u64), 591a9de470cSBruce Richardson }, 592a9de470cSBruce Richardson { 593a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 594a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 595a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 596a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[3].u64), 597a9de470cSBruce Richardson }, 598a9de470cSBruce Richardson { 599a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 600a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 601a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 602a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 603a9de470cSBruce Richardson }, 604a9de470cSBruce Richardson { 605a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 606a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 607a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 608a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 609a9de470cSBruce Richardson }, 610a9de470cSBruce Richardson { 611a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 612a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 613a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 614a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[2].u32), 615a9de470cSBruce Richardson }, 616a9de470cSBruce Richardson { 617a9de470cSBruce Richardson .code = (BPF_ALU | BPF_AND | BPF_K), 618a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 6193ac2dffaSKonstantin Ananyev .imm = TEST_SHIFT64_MASK, 620a9de470cSBruce Richardson }, 621a9de470cSBruce Richardson { 622a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_ARSH | BPF_X), 623a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 624a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 625a9de470cSBruce Richardson }, 626a9de470cSBruce Richardson { 627a9de470cSBruce Richardson .code = (BPF_ALU | BPF_AND | BPF_K), 628a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 6293ac2dffaSKonstantin Ananyev .imm = TEST_SHIFT32_MASK, 630a9de470cSBruce Richardson }, 631a9de470cSBruce Richardson { 632a9de470cSBruce Richardson .code = (BPF_ALU | BPF_LSH | BPF_X), 633a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 634a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 635a9de470cSBruce Richardson }, 636a9de470cSBruce Richardson { 637a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 638a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 639a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 640a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[4].u64), 641a9de470cSBruce Richardson }, 642a9de470cSBruce Richardson { 643a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 644a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 645a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 646a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[5].u64), 647a9de470cSBruce Richardson }, 648a9de470cSBruce Richardson /* return 1 */ 649a9de470cSBruce Richardson { 650a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 651a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 652a9de470cSBruce Richardson .imm = 1, 653a9de470cSBruce Richardson }, 654a9de470cSBruce Richardson { 655a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 656a9de470cSBruce Richardson }, 657a9de470cSBruce Richardson }; 658a9de470cSBruce Richardson 659a9de470cSBruce Richardson static void 660a9de470cSBruce Richardson test_shift1_prepare(void *arg) 661a9de470cSBruce Richardson { 662a9de470cSBruce Richardson struct dummy_vect8 *dv; 663a9de470cSBruce Richardson uint64_t v; 664a9de470cSBruce Richardson 665a9de470cSBruce Richardson dv = arg; 666a9de470cSBruce Richardson 667a9de470cSBruce Richardson v = rte_rand(); 668a9de470cSBruce Richardson 669a9de470cSBruce Richardson memset(dv, 0, sizeof(*dv)); 670a9de470cSBruce Richardson dv->in[0].u32 = v; 671a9de470cSBruce Richardson dv->in[1].u64 = v << 12 | v >> 6; 672a9de470cSBruce Richardson dv->in[2].u32 = (-v ^ 5); 673a9de470cSBruce Richardson } 674a9de470cSBruce Richardson 675a9de470cSBruce Richardson static int 676a9de470cSBruce Richardson test_shift1_check(uint64_t rc, const void *arg) 677a9de470cSBruce Richardson { 678a9de470cSBruce Richardson uint64_t r2, r3, r4; 679a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 680a9de470cSBruce Richardson struct dummy_vect8 dve; 681a9de470cSBruce Richardson 682a9de470cSBruce Richardson dvt = arg; 683a9de470cSBruce Richardson memset(&dve, 0, sizeof(dve)); 684a9de470cSBruce Richardson 685a9de470cSBruce Richardson r2 = dvt->in[0].u32; 686a9de470cSBruce Richardson r3 = dvt->in[1].u64; 687a9de470cSBruce Richardson r4 = dvt->in[2].u32; 688a9de470cSBruce Richardson 689a9de470cSBruce Richardson r2 = (uint32_t)r2 << TEST_SHIFT_1; 690a9de470cSBruce Richardson r3 = (int64_t)r3 >> TEST_SHIFT_2; 691a9de470cSBruce Richardson 692a9de470cSBruce Richardson dve.out[0].u64 = r2; 693a9de470cSBruce Richardson dve.out[1].u64 = r3; 694a9de470cSBruce Richardson 6953ac2dffaSKonstantin Ananyev r4 &= TEST_SHIFT64_MASK; 696a9de470cSBruce Richardson r3 <<= r4; 6973ac2dffaSKonstantin Ananyev r4 &= TEST_SHIFT32_MASK; 6983ac2dffaSKonstantin Ananyev r2 = (uint32_t)r2 >> r4; 699a9de470cSBruce Richardson 700a9de470cSBruce Richardson dve.out[2].u64 = r2; 701a9de470cSBruce Richardson dve.out[3].u64 = r3; 702a9de470cSBruce Richardson 703a9de470cSBruce Richardson r2 = dvt->in[0].u32; 704a9de470cSBruce Richardson r3 = dvt->in[1].u64; 705a9de470cSBruce Richardson r4 = dvt->in[2].u32; 706a9de470cSBruce Richardson 7073ac2dffaSKonstantin Ananyev r2 &= TEST_SHIFT64_MASK; 708a9de470cSBruce Richardson r3 = (int64_t)r3 >> r2; 7093ac2dffaSKonstantin Ananyev r2 &= TEST_SHIFT32_MASK; 710a9de470cSBruce Richardson r4 = (uint32_t)r4 << r2; 711a9de470cSBruce Richardson 712a9de470cSBruce Richardson dve.out[4].u64 = r4; 713a9de470cSBruce Richardson dve.out[5].u64 = r3; 714a9de470cSBruce Richardson 715a9de470cSBruce Richardson return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); 716a9de470cSBruce Richardson } 717a9de470cSBruce Richardson 718a9de470cSBruce Richardson /* jmp test-cases */ 719a9de470cSBruce Richardson static const struct ebpf_insn test_jump1_prog[] = { 720a9de470cSBruce Richardson 721a9de470cSBruce Richardson [0] = { 722a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 723a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 724a9de470cSBruce Richardson .imm = 0, 725a9de470cSBruce Richardson }, 726a9de470cSBruce Richardson [1] = { 727a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 728a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 729a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 730a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 731a9de470cSBruce Richardson }, 732a9de470cSBruce Richardson [2] = { 733a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 734a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 735a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 736a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u64), 737a9de470cSBruce Richardson }, 738a9de470cSBruce Richardson [3] = { 739a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 740a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 741a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 742a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u32), 743a9de470cSBruce Richardson }, 744a9de470cSBruce Richardson [4] = { 745a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 746a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 747a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 748a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 749a9de470cSBruce Richardson }, 750a9de470cSBruce Richardson [5] = { 751a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JEQ | BPF_K), 752a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 753a9de470cSBruce Richardson .imm = TEST_JCC_1, 754a9de470cSBruce Richardson .off = 8, 755a9de470cSBruce Richardson }, 756a9de470cSBruce Richardson [6] = { 757a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_JSLE | BPF_K), 758a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 759a9de470cSBruce Richardson .imm = TEST_JCC_2, 760a9de470cSBruce Richardson .off = 9, 761a9de470cSBruce Richardson }, 762a9de470cSBruce Richardson [7] = { 763a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JGT | BPF_K), 764a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 765a9de470cSBruce Richardson .imm = TEST_JCC_3, 766a9de470cSBruce Richardson .off = 10, 767a9de470cSBruce Richardson }, 768a9de470cSBruce Richardson [8] = { 769a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JSET | BPF_K), 770a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 771a9de470cSBruce Richardson .imm = TEST_JCC_4, 772a9de470cSBruce Richardson .off = 11, 773a9de470cSBruce Richardson }, 774a9de470cSBruce Richardson [9] = { 775a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_JNE | BPF_X), 776a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 777a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 778a9de470cSBruce Richardson .off = 12, 779a9de470cSBruce Richardson }, 780a9de470cSBruce Richardson [10] = { 781a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_JSGT | BPF_X), 782a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 783a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 784a9de470cSBruce Richardson .off = 13, 785a9de470cSBruce Richardson }, 786a9de470cSBruce Richardson [11] = { 787a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_JLE | BPF_X), 788a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 789a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 790a9de470cSBruce Richardson .off = 14, 791a9de470cSBruce Richardson }, 792a9de470cSBruce Richardson [12] = { 793a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JSET | BPF_X), 794a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 795a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 796a9de470cSBruce Richardson .off = 15, 797a9de470cSBruce Richardson }, 798a9de470cSBruce Richardson [13] = { 799a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 800a9de470cSBruce Richardson }, 801a9de470cSBruce Richardson [14] = { 802a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 803a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 804a9de470cSBruce Richardson .imm = 0x1, 805a9de470cSBruce Richardson }, 806a9de470cSBruce Richardson [15] = { 807a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 808a9de470cSBruce Richardson .off = -10, 809a9de470cSBruce Richardson }, 810a9de470cSBruce Richardson [16] = { 811a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 812a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 813a9de470cSBruce Richardson .imm = 0x2, 814a9de470cSBruce Richardson }, 815a9de470cSBruce Richardson [17] = { 816a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 817a9de470cSBruce Richardson .off = -11, 818a9de470cSBruce Richardson }, 819a9de470cSBruce Richardson [18] = { 820a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 821a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 822a9de470cSBruce Richardson .imm = 0x4, 823a9de470cSBruce Richardson }, 824a9de470cSBruce Richardson [19] = { 825a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 826a9de470cSBruce Richardson .off = -12, 827a9de470cSBruce Richardson }, 828a9de470cSBruce Richardson [20] = { 829a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 830a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 831a9de470cSBruce Richardson .imm = 0x8, 832a9de470cSBruce Richardson }, 833a9de470cSBruce Richardson [21] = { 834a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 835a9de470cSBruce Richardson .off = -13, 836a9de470cSBruce Richardson }, 837a9de470cSBruce Richardson [22] = { 838a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 839a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 840a9de470cSBruce Richardson .imm = 0x10, 841a9de470cSBruce Richardson }, 842a9de470cSBruce Richardson [23] = { 843a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 844a9de470cSBruce Richardson .off = -14, 845a9de470cSBruce Richardson }, 846a9de470cSBruce Richardson [24] = { 847a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 848a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 849a9de470cSBruce Richardson .imm = 0x20, 850a9de470cSBruce Richardson }, 851a9de470cSBruce Richardson [25] = { 852a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 853a9de470cSBruce Richardson .off = -15, 854a9de470cSBruce Richardson }, 855a9de470cSBruce Richardson [26] = { 856a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 857a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 858a9de470cSBruce Richardson .imm = 0x40, 859a9de470cSBruce Richardson }, 860a9de470cSBruce Richardson [27] = { 861a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 862a9de470cSBruce Richardson .off = -16, 863a9de470cSBruce Richardson }, 864a9de470cSBruce Richardson [28] = { 865a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 866a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 867a9de470cSBruce Richardson .imm = 0x80, 868a9de470cSBruce Richardson }, 869a9de470cSBruce Richardson [29] = { 870a9de470cSBruce Richardson .code = (BPF_JMP | BPF_JA), 871a9de470cSBruce Richardson .off = -17, 872a9de470cSBruce Richardson }, 873a9de470cSBruce Richardson }; 874a9de470cSBruce Richardson 875a9de470cSBruce Richardson static void 876a9de470cSBruce Richardson test_jump1_prepare(void *arg) 877a9de470cSBruce Richardson { 878a9de470cSBruce Richardson struct dummy_vect8 *dv; 879a9de470cSBruce Richardson uint64_t v1, v2; 880a9de470cSBruce Richardson 881a9de470cSBruce Richardson dv = arg; 882a9de470cSBruce Richardson 883a9de470cSBruce Richardson v1 = rte_rand(); 884a9de470cSBruce Richardson v2 = rte_rand(); 885a9de470cSBruce Richardson 886a9de470cSBruce Richardson memset(dv, 0, sizeof(*dv)); 887a9de470cSBruce Richardson dv->in[0].u64 = v1; 888a9de470cSBruce Richardson dv->in[1].u64 = v2; 889a9de470cSBruce Richardson dv->in[0].u32 = (v1 << 12) + (v2 >> 6); 890a9de470cSBruce Richardson dv->in[1].u32 = (v2 << 12) - (v1 >> 6); 891a9de470cSBruce Richardson } 892a9de470cSBruce Richardson 893a9de470cSBruce Richardson static int 894a9de470cSBruce Richardson test_jump1_check(uint64_t rc, const void *arg) 895a9de470cSBruce Richardson { 896a9de470cSBruce Richardson uint64_t r2, r3, r4, r5, rv; 897a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 898a9de470cSBruce Richardson 899a9de470cSBruce Richardson dvt = arg; 900a9de470cSBruce Richardson 901a9de470cSBruce Richardson rv = 0; 902a9de470cSBruce Richardson r2 = dvt->in[0].u32; 903a9de470cSBruce Richardson r3 = dvt->in[0].u64; 904a9de470cSBruce Richardson r4 = dvt->in[1].u32; 905a9de470cSBruce Richardson r5 = dvt->in[1].u64; 906a9de470cSBruce Richardson 907a9de470cSBruce Richardson if (r2 == TEST_JCC_1) 908a9de470cSBruce Richardson rv |= 0x1; 909a9de470cSBruce Richardson if ((int64_t)r3 <= TEST_JCC_2) 910a9de470cSBruce Richardson rv |= 0x2; 911a9de470cSBruce Richardson if (r4 > TEST_JCC_3) 912a9de470cSBruce Richardson rv |= 0x4; 913a9de470cSBruce Richardson if (r5 & TEST_JCC_4) 914a9de470cSBruce Richardson rv |= 0x8; 915a9de470cSBruce Richardson if (r2 != r3) 916a9de470cSBruce Richardson rv |= 0x10; 917a9de470cSBruce Richardson if ((int64_t)r2 > (int64_t)r4) 918a9de470cSBruce Richardson rv |= 0x20; 919a9de470cSBruce Richardson if (r2 <= r5) 920a9de470cSBruce Richardson rv |= 0x40; 921a9de470cSBruce Richardson if (r3 & r5) 922a9de470cSBruce Richardson rv |= 0x80; 923a9de470cSBruce Richardson 924a9de470cSBruce Richardson return cmp_res(__func__, rv, rc, &rv, &rc, sizeof(rv)); 925a9de470cSBruce Richardson } 926a9de470cSBruce Richardson 927cddd8795SHarman Kalra /* Jump test case - check ip4_dest in particular subnet */ 928cddd8795SHarman Kalra static const struct ebpf_insn test_jump2_prog[] = { 929cddd8795SHarman Kalra 930cddd8795SHarman Kalra [0] = { 931cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 932cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 933cddd8795SHarman Kalra .imm = 0xe, 934cddd8795SHarman Kalra }, 935cddd8795SHarman Kalra [1] = { 936cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_H), 937cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 938cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 939cddd8795SHarman Kalra .off = 12, 940cddd8795SHarman Kalra }, 941cddd8795SHarman Kalra [2] = { 942cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_JNE | BPF_K), 943cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 944cddd8795SHarman Kalra .off = 2, 945cddd8795SHarman Kalra .imm = 0x81, 946cddd8795SHarman Kalra }, 947cddd8795SHarman Kalra [3] = { 948cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 949cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 950cddd8795SHarman Kalra .imm = 0x12, 951cddd8795SHarman Kalra }, 952cddd8795SHarman Kalra [4] = { 953cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_H), 954cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 955cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 956cddd8795SHarman Kalra .off = 16, 957cddd8795SHarman Kalra }, 958cddd8795SHarman Kalra [5] = { 959cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_AND | BPF_K), 960cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 961cddd8795SHarman Kalra .imm = 0xffff, 962cddd8795SHarman Kalra }, 963cddd8795SHarman Kalra [6] = { 964cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_JNE | BPF_K), 965cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 966cddd8795SHarman Kalra .off = 9, 967cddd8795SHarman Kalra .imm = 0x8, 968cddd8795SHarman Kalra }, 969cddd8795SHarman Kalra [7] = { 970cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 971cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 972cddd8795SHarman Kalra .src_reg = EBPF_REG_2, 973cddd8795SHarman Kalra }, 974cddd8795SHarman Kalra [8] = { 975cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 976cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 977cddd8795SHarman Kalra .imm = 0, 978cddd8795SHarman Kalra }, 979cddd8795SHarman Kalra [9] = { 980cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_W), 981cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 982cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 983cddd8795SHarman Kalra .off = 16, 984cddd8795SHarman Kalra }, 985cddd8795SHarman Kalra [10] = { 986cddd8795SHarman Kalra .code = (BPF_ALU | EBPF_MOV | BPF_K), 987cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 988cddd8795SHarman Kalra .imm = TEST_NETMASK, 989cddd8795SHarman Kalra }, 990cddd8795SHarman Kalra [11] = { 991cddd8795SHarman Kalra .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), 992cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 993cddd8795SHarman Kalra .imm = sizeof(uint32_t) * CHAR_BIT, 994cddd8795SHarman Kalra }, 995cddd8795SHarman Kalra [12] = { 996cddd8795SHarman Kalra .code = (BPF_ALU | BPF_AND | BPF_X), 997cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 998cddd8795SHarman Kalra .src_reg = EBPF_REG_3, 999cddd8795SHarman Kalra }, 1000cddd8795SHarman Kalra [13] = { 1001cddd8795SHarman Kalra .code = (BPF_ALU | EBPF_MOV | BPF_K), 1002cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 1003cddd8795SHarman Kalra .imm = TEST_SUBNET, 1004cddd8795SHarman Kalra }, 1005cddd8795SHarman Kalra [14] = { 1006cddd8795SHarman Kalra .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), 1007cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 1008cddd8795SHarman Kalra .imm = sizeof(uint32_t) * CHAR_BIT, 1009cddd8795SHarman Kalra }, 1010cddd8795SHarman Kalra [15] = { 1011cddd8795SHarman Kalra .code = (BPF_JMP | BPF_JEQ | BPF_X), 1012cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 1013cddd8795SHarman Kalra .src_reg = EBPF_REG_3, 1014cddd8795SHarman Kalra .off = 1, 1015cddd8795SHarman Kalra }, 1016cddd8795SHarman Kalra [16] = { 1017cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1018cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 1019cddd8795SHarman Kalra .imm = -1, 1020cddd8795SHarman Kalra }, 1021cddd8795SHarman Kalra [17] = { 1022cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_EXIT), 1023cddd8795SHarman Kalra }, 1024cddd8795SHarman Kalra }; 1025cddd8795SHarman Kalra 1026cddd8795SHarman Kalra /* Preparing a vlan packet */ 1027cddd8795SHarman Kalra static void 1028cddd8795SHarman Kalra test_jump2_prepare(void *arg) 1029cddd8795SHarman Kalra { 1030cddd8795SHarman Kalra struct dummy_net *dn; 1031cddd8795SHarman Kalra 1032cddd8795SHarman Kalra dn = arg; 1033cddd8795SHarman Kalra memset(dn, 0, sizeof(*dn)); 1034cddd8795SHarman Kalra 1035cddd8795SHarman Kalra /* 1036cddd8795SHarman Kalra * Initialize ether header. 1037cddd8795SHarman Kalra */ 1038cddd8795SHarman Kalra rte_ether_addr_copy((struct rte_ether_addr *)dst_mac, 103904d43857SDmitry Kozlyuk &dn->eth_hdr.dst_addr); 1040cddd8795SHarman Kalra rte_ether_addr_copy((struct rte_ether_addr *)src_mac, 104104d43857SDmitry Kozlyuk &dn->eth_hdr.src_addr); 1042cddd8795SHarman Kalra dn->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); 1043cddd8795SHarman Kalra 1044cddd8795SHarman Kalra /* 1045cddd8795SHarman Kalra * Initialize vlan header. 1046cddd8795SHarman Kalra */ 1047cddd8795SHarman Kalra dn->vlan_hdr.eth_proto = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); 1048cddd8795SHarman Kalra dn->vlan_hdr.vlan_tci = 32; 1049cddd8795SHarman Kalra 1050cddd8795SHarman Kalra /* 1051cddd8795SHarman Kalra * Initialize IP header. 1052cddd8795SHarman Kalra */ 1053cddd8795SHarman Kalra dn->ip_hdr.version_ihl = 0x45; /*IP_VERSION | IP_HDRLEN*/ 1054cddd8795SHarman Kalra dn->ip_hdr.time_to_live = 64; /* IP_DEFTTL */ 1055cddd8795SHarman Kalra dn->ip_hdr.next_proto_id = IPPROTO_TCP; 1056cddd8795SHarman Kalra dn->ip_hdr.packet_id = rte_cpu_to_be_16(0x463c); 1057cddd8795SHarman Kalra dn->ip_hdr.total_length = rte_cpu_to_be_16(60); 1058cddd8795SHarman Kalra dn->ip_hdr.src_addr = rte_cpu_to_be_32(ip_src_addr); 1059cddd8795SHarman Kalra dn->ip_hdr.dst_addr = rte_cpu_to_be_32(ip_dst_addr); 1060cddd8795SHarman Kalra } 1061cddd8795SHarman Kalra 1062cddd8795SHarman Kalra static int 1063cddd8795SHarman Kalra test_jump2_check(uint64_t rc, const void *arg) 1064cddd8795SHarman Kalra { 1065cddd8795SHarman Kalra const struct rte_ether_hdr *eth_hdr = arg; 1066cddd8795SHarman Kalra const struct rte_ipv4_hdr *ipv4_hdr; 1067cddd8795SHarman Kalra const void *next = eth_hdr; 1068cddd8795SHarman Kalra uint16_t eth_type; 1069cddd8795SHarman Kalra uint64_t v = -1; 1070cddd8795SHarman Kalra 1071cddd8795SHarman Kalra if (eth_hdr->ether_type == htons(0x8100)) { 1072cddd8795SHarman Kalra const struct rte_vlan_hdr *vlan_hdr = 1073cddd8795SHarman Kalra (const void *)(eth_hdr + 1); 1074cddd8795SHarman Kalra eth_type = vlan_hdr->eth_proto; 1075cddd8795SHarman Kalra next = vlan_hdr + 1; 1076cddd8795SHarman Kalra } else { 1077cddd8795SHarman Kalra eth_type = eth_hdr->ether_type; 1078cddd8795SHarman Kalra next = eth_hdr + 1; 1079cddd8795SHarman Kalra } 1080cddd8795SHarman Kalra 1081cddd8795SHarman Kalra if (eth_type == htons(0x0800)) { 1082cddd8795SHarman Kalra ipv4_hdr = next; 1083cddd8795SHarman Kalra if ((ipv4_hdr->dst_addr & rte_cpu_to_be_32(TEST_NETMASK)) == 1084cddd8795SHarman Kalra rte_cpu_to_be_32(TEST_SUBNET)) { 1085cddd8795SHarman Kalra v = 0; 1086cddd8795SHarman Kalra } 1087cddd8795SHarman Kalra } 1088cddd8795SHarman Kalra 1089cddd8795SHarman Kalra return cmp_res(__func__, v, rc, arg, arg, sizeof(arg)); 1090cddd8795SHarman Kalra } 1091cddd8795SHarman Kalra 1092a9de470cSBruce Richardson /* alu (add, sub, and, or, xor, neg) test-cases */ 1093a9de470cSBruce Richardson static const struct ebpf_insn test_alu1_prog[] = { 1094a9de470cSBruce Richardson 1095a9de470cSBruce Richardson { 1096a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1097a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1098a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1099a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 1100a9de470cSBruce Richardson }, 1101a9de470cSBruce Richardson { 1102a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1103a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1104a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1105a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u64), 1106a9de470cSBruce Richardson }, 1107a9de470cSBruce Richardson { 1108a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1109a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1110a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1111a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u32), 1112a9de470cSBruce Richardson }, 1113a9de470cSBruce Richardson { 1114a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1115a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 1116a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1117a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 1118a9de470cSBruce Richardson }, 1119a9de470cSBruce Richardson { 1120a9de470cSBruce Richardson .code = (BPF_ALU | BPF_AND | BPF_K), 1121a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1122a9de470cSBruce Richardson .imm = TEST_FILL_1, 1123a9de470cSBruce Richardson }, 1124a9de470cSBruce Richardson { 1125a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 1126a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1127a9de470cSBruce Richardson .imm = TEST_FILL_1, 1128a9de470cSBruce Richardson }, 1129a9de470cSBruce Richardson { 1130a9de470cSBruce Richardson .code = (BPF_ALU | BPF_XOR | BPF_K), 1131a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1132a9de470cSBruce Richardson .imm = TEST_FILL_1, 1133a9de470cSBruce Richardson }, 1134a9de470cSBruce Richardson { 1135a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 1136a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 1137a9de470cSBruce Richardson .imm = TEST_FILL_1, 1138a9de470cSBruce Richardson }, 1139a9de470cSBruce Richardson { 1140a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1141a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1142a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1143a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[0].u64), 1144a9de470cSBruce Richardson }, 1145a9de470cSBruce Richardson { 1146a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1147a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1148a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1149a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[1].u64), 1150a9de470cSBruce Richardson }, 1151a9de470cSBruce Richardson { 1152a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1153a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1154a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1155a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[2].u64), 1156a9de470cSBruce Richardson }, 1157a9de470cSBruce Richardson { 1158a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1159a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1160a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 1161a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[3].u64), 1162a9de470cSBruce Richardson }, 1163a9de470cSBruce Richardson { 1164a9de470cSBruce Richardson .code = (BPF_ALU | BPF_OR | BPF_X), 1165a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1166a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1167a9de470cSBruce Richardson }, 1168a9de470cSBruce Richardson { 1169a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_XOR | BPF_X), 1170a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1171a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1172a9de470cSBruce Richardson }, 1173a9de470cSBruce Richardson { 1174a9de470cSBruce Richardson .code = (BPF_ALU | BPF_SUB | BPF_X), 1175a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1176a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 1177a9de470cSBruce Richardson }, 1178a9de470cSBruce Richardson { 1179a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_AND | BPF_X), 1180a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 1181a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1182a9de470cSBruce Richardson }, 1183a9de470cSBruce Richardson { 1184a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1185a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1186a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1187a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[4].u64), 1188a9de470cSBruce Richardson }, 1189a9de470cSBruce Richardson { 1190a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1191a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1192a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1193a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[5].u64), 1194a9de470cSBruce Richardson }, 1195a9de470cSBruce Richardson { 1196a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1197a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1198a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1199a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[6].u64), 1200a9de470cSBruce Richardson }, 1201a9de470cSBruce Richardson { 1202a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1203a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1204a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 1205a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[7].u64), 1206a9de470cSBruce Richardson }, 1207a9de470cSBruce Richardson /* return (-r2 + (-r3)) */ 1208a9de470cSBruce Richardson { 1209a9de470cSBruce Richardson .code = (BPF_ALU | BPF_NEG), 1210a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1211a9de470cSBruce Richardson }, 1212a9de470cSBruce Richardson { 1213a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_NEG), 1214a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1215a9de470cSBruce Richardson }, 1216a9de470cSBruce Richardson { 1217a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 1218a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1219a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1220a9de470cSBruce Richardson }, 1221a9de470cSBruce Richardson { 1222a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 1223a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1224a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1225a9de470cSBruce Richardson }, 1226a9de470cSBruce Richardson { 1227a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1228a9de470cSBruce Richardson }, 1229a9de470cSBruce Richardson }; 1230a9de470cSBruce Richardson 1231a9de470cSBruce Richardson static int 1232a9de470cSBruce Richardson test_alu1_check(uint64_t rc, const void *arg) 1233a9de470cSBruce Richardson { 1234a9de470cSBruce Richardson uint64_t r2, r3, r4, r5, rv; 1235a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 1236a9de470cSBruce Richardson struct dummy_vect8 dve; 1237a9de470cSBruce Richardson 1238a9de470cSBruce Richardson dvt = arg; 1239a9de470cSBruce Richardson memset(&dve, 0, sizeof(dve)); 1240a9de470cSBruce Richardson 1241a9de470cSBruce Richardson r2 = dvt->in[0].u32; 1242a9de470cSBruce Richardson r3 = dvt->in[0].u64; 1243a9de470cSBruce Richardson r4 = dvt->in[1].u32; 1244a9de470cSBruce Richardson r5 = dvt->in[1].u64; 1245a9de470cSBruce Richardson 1246a9de470cSBruce Richardson r2 = (uint32_t)r2 & TEST_FILL_1; 1247a9de470cSBruce Richardson r3 |= (int32_t) TEST_FILL_1; 1248a9de470cSBruce Richardson r4 = (uint32_t)r4 ^ TEST_FILL_1; 1249a9de470cSBruce Richardson r5 += (int32_t)TEST_FILL_1; 1250a9de470cSBruce Richardson 1251a9de470cSBruce Richardson dve.out[0].u64 = r2; 1252a9de470cSBruce Richardson dve.out[1].u64 = r3; 1253a9de470cSBruce Richardson dve.out[2].u64 = r4; 1254a9de470cSBruce Richardson dve.out[3].u64 = r5; 1255a9de470cSBruce Richardson 1256a9de470cSBruce Richardson r2 = (uint32_t)r2 | (uint32_t)r3; 1257a9de470cSBruce Richardson r3 ^= r4; 1258a9de470cSBruce Richardson r4 = (uint32_t)r4 - (uint32_t)r5; 1259a9de470cSBruce Richardson r5 &= r2; 1260a9de470cSBruce Richardson 1261a9de470cSBruce Richardson dve.out[4].u64 = r2; 1262a9de470cSBruce Richardson dve.out[5].u64 = r3; 1263a9de470cSBruce Richardson dve.out[6].u64 = r4; 1264a9de470cSBruce Richardson dve.out[7].u64 = r5; 1265a9de470cSBruce Richardson 1266a9de470cSBruce Richardson r2 = -(int32_t)r2; 1267a9de470cSBruce Richardson rv = (uint32_t)r2; 1268a9de470cSBruce Richardson r3 = -r3; 1269a9de470cSBruce Richardson rv += r3; 1270a9de470cSBruce Richardson 1271a9de470cSBruce Richardson return cmp_res(__func__, rv, rc, dve.out, dvt->out, sizeof(dve.out)); 1272a9de470cSBruce Richardson } 1273a9de470cSBruce Richardson 1274a9de470cSBruce Richardson /* endianness conversions (BE->LE/LE->BE) test-cases */ 1275a9de470cSBruce Richardson static const struct ebpf_insn test_bele1_prog[] = { 1276a9de470cSBruce Richardson 1277a9de470cSBruce Richardson { 1278a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_H), 1279a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1280a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1281a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u16), 1282a9de470cSBruce Richardson }, 1283a9de470cSBruce Richardson { 1284a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1285a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1286a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1287a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 1288a9de470cSBruce Richardson }, 1289a9de470cSBruce Richardson { 1290a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1291a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1292a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1293a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u64), 1294a9de470cSBruce Richardson }, 1295a9de470cSBruce Richardson { 1296a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), 1297a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1298a9de470cSBruce Richardson .imm = sizeof(uint16_t) * CHAR_BIT, 1299a9de470cSBruce Richardson }, 1300a9de470cSBruce Richardson { 1301a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), 1302a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1303a9de470cSBruce Richardson .imm = sizeof(uint32_t) * CHAR_BIT, 1304a9de470cSBruce Richardson }, 1305a9de470cSBruce Richardson { 1306a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_BE), 1307a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1308a9de470cSBruce Richardson .imm = sizeof(uint64_t) * CHAR_BIT, 1309a9de470cSBruce Richardson }, 1310a9de470cSBruce Richardson { 1311a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1312a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1313a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1314a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[0].u64), 1315a9de470cSBruce Richardson }, 1316a9de470cSBruce Richardson { 1317a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1318a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1319a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1320a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[1].u64), 1321a9de470cSBruce Richardson }, 1322a9de470cSBruce Richardson { 1323a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1324a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1325a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1326a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[2].u64), 1327a9de470cSBruce Richardson }, 1328a9de470cSBruce Richardson { 1329a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_H), 1330a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1331a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1332a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u16), 1333a9de470cSBruce Richardson }, 1334a9de470cSBruce Richardson { 1335a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1336a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1337a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1338a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 1339a9de470cSBruce Richardson }, 1340a9de470cSBruce Richardson { 1341a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1342a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1343a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1344a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u64), 1345a9de470cSBruce Richardson }, 1346a9de470cSBruce Richardson { 1347a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), 1348a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1349a9de470cSBruce Richardson .imm = sizeof(uint16_t) * CHAR_BIT, 1350a9de470cSBruce Richardson }, 1351a9de470cSBruce Richardson { 1352a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), 1353a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1354a9de470cSBruce Richardson .imm = sizeof(uint32_t) * CHAR_BIT, 1355a9de470cSBruce Richardson }, 1356a9de470cSBruce Richardson { 1357a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_END | EBPF_TO_LE), 1358a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1359a9de470cSBruce Richardson .imm = sizeof(uint64_t) * CHAR_BIT, 1360a9de470cSBruce Richardson }, 1361a9de470cSBruce Richardson { 1362a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1363a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1364a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1365a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[3].u64), 1366a9de470cSBruce Richardson }, 1367a9de470cSBruce Richardson { 1368a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1369a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1370a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1371a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[4].u64), 1372a9de470cSBruce Richardson }, 1373a9de470cSBruce Richardson { 1374a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1375a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1376a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1377a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[5].u64), 1378a9de470cSBruce Richardson }, 1379a9de470cSBruce Richardson /* return 1 */ 1380a9de470cSBruce Richardson { 1381a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 1382a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1383a9de470cSBruce Richardson .imm = 1, 1384a9de470cSBruce Richardson }, 1385a9de470cSBruce Richardson { 1386a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1387a9de470cSBruce Richardson }, 1388a9de470cSBruce Richardson }; 1389a9de470cSBruce Richardson 1390a9de470cSBruce Richardson static void 1391a9de470cSBruce Richardson test_bele1_prepare(void *arg) 1392a9de470cSBruce Richardson { 1393a9de470cSBruce Richardson struct dummy_vect8 *dv; 1394a9de470cSBruce Richardson 1395a9de470cSBruce Richardson dv = arg; 1396a9de470cSBruce Richardson 1397a9de470cSBruce Richardson memset(dv, 0, sizeof(*dv)); 1398a9de470cSBruce Richardson dv->in[0].u64 = rte_rand(); 1399a9de470cSBruce Richardson dv->in[0].u32 = dv->in[0].u64; 1400a9de470cSBruce Richardson dv->in[0].u16 = dv->in[0].u64; 1401a9de470cSBruce Richardson } 1402a9de470cSBruce Richardson 1403a9de470cSBruce Richardson static int 1404a9de470cSBruce Richardson test_bele1_check(uint64_t rc, const void *arg) 1405a9de470cSBruce Richardson { 1406a9de470cSBruce Richardson uint64_t r2, r3, r4; 1407a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 1408a9de470cSBruce Richardson struct dummy_vect8 dve; 1409a9de470cSBruce Richardson 1410a9de470cSBruce Richardson dvt = arg; 1411a9de470cSBruce Richardson memset(&dve, 0, sizeof(dve)); 1412a9de470cSBruce Richardson 1413a9de470cSBruce Richardson r2 = dvt->in[0].u16; 1414a9de470cSBruce Richardson r3 = dvt->in[0].u32; 1415a9de470cSBruce Richardson r4 = dvt->in[0].u64; 1416a9de470cSBruce Richardson 1417a9de470cSBruce Richardson r2 = rte_cpu_to_be_16(r2); 1418a9de470cSBruce Richardson r3 = rte_cpu_to_be_32(r3); 1419a9de470cSBruce Richardson r4 = rte_cpu_to_be_64(r4); 1420a9de470cSBruce Richardson 1421a9de470cSBruce Richardson dve.out[0].u64 = r2; 1422a9de470cSBruce Richardson dve.out[1].u64 = r3; 1423a9de470cSBruce Richardson dve.out[2].u64 = r4; 1424a9de470cSBruce Richardson 1425a9de470cSBruce Richardson r2 = dvt->in[0].u16; 1426a9de470cSBruce Richardson r3 = dvt->in[0].u32; 1427a9de470cSBruce Richardson r4 = dvt->in[0].u64; 1428a9de470cSBruce Richardson 1429a9de470cSBruce Richardson r2 = rte_cpu_to_le_16(r2); 1430a9de470cSBruce Richardson r3 = rte_cpu_to_le_32(r3); 1431a9de470cSBruce Richardson r4 = rte_cpu_to_le_64(r4); 1432a9de470cSBruce Richardson 1433a9de470cSBruce Richardson dve.out[3].u64 = r2; 1434a9de470cSBruce Richardson dve.out[4].u64 = r3; 1435a9de470cSBruce Richardson dve.out[5].u64 = r4; 1436a9de470cSBruce Richardson 1437a9de470cSBruce Richardson return cmp_res(__func__, 1, rc, dve.out, dvt->out, sizeof(dve.out)); 1438a9de470cSBruce Richardson } 1439a9de470cSBruce Richardson 1440a9de470cSBruce Richardson /* atomic add test-cases */ 1441a9de470cSBruce Richardson static const struct ebpf_insn test_xadd1_prog[] = { 1442a9de470cSBruce Richardson 1443a9de470cSBruce Richardson { 1444a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1445a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1446a9de470cSBruce Richardson .imm = 1, 1447a9de470cSBruce Richardson }, 1448a9de470cSBruce Richardson { 1449a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1450a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1451a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1452a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1453a9de470cSBruce Richardson }, 1454a9de470cSBruce Richardson { 1455a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1456a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1457a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1458a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1459a9de470cSBruce Richardson }, 1460a9de470cSBruce Richardson { 1461a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1462a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1463a9de470cSBruce Richardson .imm = -1, 1464a9de470cSBruce Richardson }, 1465a9de470cSBruce Richardson { 1466a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1467a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1468a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1469a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1470a9de470cSBruce Richardson }, 1471a9de470cSBruce Richardson { 1472a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1473a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1474a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1475a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1476a9de470cSBruce Richardson }, 1477a9de470cSBruce Richardson { 1478a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1479a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1480a9de470cSBruce Richardson .imm = TEST_FILL_1, 1481a9de470cSBruce Richardson }, 1482a9de470cSBruce Richardson { 1483a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1484a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1485a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1486a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1487a9de470cSBruce Richardson }, 1488a9de470cSBruce Richardson { 1489a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1490a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1491a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1492a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1493a9de470cSBruce Richardson }, 1494a9de470cSBruce Richardson { 1495a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1496a9de470cSBruce Richardson .dst_reg = EBPF_REG_5, 1497a9de470cSBruce Richardson .imm = TEST_MUL_1, 1498a9de470cSBruce Richardson }, 1499a9de470cSBruce Richardson { 1500a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1501a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1502a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 1503a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1504a9de470cSBruce Richardson }, 1505a9de470cSBruce Richardson { 1506a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1507a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1508a9de470cSBruce Richardson .src_reg = EBPF_REG_5, 1509a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1510a9de470cSBruce Richardson }, 1511a9de470cSBruce Richardson { 1512a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1513a9de470cSBruce Richardson .dst_reg = EBPF_REG_6, 1514a9de470cSBruce Richardson .imm = TEST_MUL_2, 1515a9de470cSBruce Richardson }, 1516a9de470cSBruce Richardson { 1517a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1518a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1519a9de470cSBruce Richardson .src_reg = EBPF_REG_6, 1520a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1521a9de470cSBruce Richardson }, 1522a9de470cSBruce Richardson { 1523a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1524a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1525a9de470cSBruce Richardson .src_reg = EBPF_REG_6, 1526a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1527a9de470cSBruce Richardson }, 1528a9de470cSBruce Richardson { 1529a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1530a9de470cSBruce Richardson .dst_reg = EBPF_REG_7, 1531a9de470cSBruce Richardson .imm = TEST_JCC_2, 1532a9de470cSBruce Richardson }, 1533a9de470cSBruce Richardson { 1534a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1535a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1536a9de470cSBruce Richardson .src_reg = EBPF_REG_7, 1537a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1538a9de470cSBruce Richardson }, 1539a9de470cSBruce Richardson { 1540a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1541a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1542a9de470cSBruce Richardson .src_reg = EBPF_REG_7, 1543a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1544a9de470cSBruce Richardson }, 1545a9de470cSBruce Richardson { 1546a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 1547a9de470cSBruce Richardson .dst_reg = EBPF_REG_8, 1548a9de470cSBruce Richardson .imm = TEST_JCC_3, 1549a9de470cSBruce Richardson }, 1550a9de470cSBruce Richardson { 1551a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | BPF_W), 1552a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1553a9de470cSBruce Richardson .src_reg = EBPF_REG_8, 1554a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1555a9de470cSBruce Richardson }, 1556a9de470cSBruce Richardson { 1557a9de470cSBruce Richardson .code = (BPF_STX | EBPF_XADD | EBPF_DW), 1558a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1559a9de470cSBruce Richardson .src_reg = EBPF_REG_8, 1560a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1561a9de470cSBruce Richardson }, 1562a9de470cSBruce Richardson /* return 1 */ 1563a9de470cSBruce Richardson { 1564a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 1565a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1566a9de470cSBruce Richardson .imm = 1, 1567a9de470cSBruce Richardson }, 1568a9de470cSBruce Richardson { 1569a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1570a9de470cSBruce Richardson }, 1571a9de470cSBruce Richardson }; 1572a9de470cSBruce Richardson 1573a9de470cSBruce Richardson static int 1574a9de470cSBruce Richardson test_xadd1_check(uint64_t rc, const void *arg) 1575a9de470cSBruce Richardson { 1576a9de470cSBruce Richardson uint64_t rv; 1577a9de470cSBruce Richardson const struct dummy_offset *dft; 1578a9de470cSBruce Richardson struct dummy_offset dfe; 1579a9de470cSBruce Richardson 1580a9de470cSBruce Richardson dft = arg; 1581a9de470cSBruce Richardson memset(&dfe, 0, sizeof(dfe)); 1582a9de470cSBruce Richardson 1583a9de470cSBruce Richardson rv = 1; 1584b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1585b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1586b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1587b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1588a9de470cSBruce Richardson 1589a9de470cSBruce Richardson rv = -1; 1590b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1591b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1592b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1593b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1594a9de470cSBruce Richardson 1595a9de470cSBruce Richardson rv = (int32_t)TEST_FILL_1; 1596b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1597b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1598b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1599b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1600a9de470cSBruce Richardson 1601a9de470cSBruce Richardson rv = TEST_MUL_1; 1602b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1603b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1604b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1605b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1606a9de470cSBruce Richardson 1607a9de470cSBruce Richardson rv = TEST_MUL_2; 1608b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1609b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1610b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1611b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1612a9de470cSBruce Richardson 1613a9de470cSBruce Richardson rv = TEST_JCC_2; 1614b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1615b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1616b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1617b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1618a9de470cSBruce Richardson 1619a9de470cSBruce Richardson rv = TEST_JCC_3; 1620b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint32_t __rte_atomic *)&dfe.u32, rv, 1621b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1622b6a7e685STyler Retzlaff rte_atomic_fetch_add_explicit((uint64_t __rte_atomic *)&dfe.u64, rv, 1623b6a7e685STyler Retzlaff rte_memory_order_relaxed); 1624a9de470cSBruce Richardson 1625a9de470cSBruce Richardson return cmp_res(__func__, 1, rc, &dfe, dft, sizeof(dfe)); 1626a9de470cSBruce Richardson } 1627a9de470cSBruce Richardson 1628a9de470cSBruce Richardson /* alu div test-cases */ 1629a9de470cSBruce Richardson static const struct ebpf_insn test_div1_prog[] = { 1630a9de470cSBruce Richardson 1631a9de470cSBruce Richardson { 1632a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1633a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1634a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1635a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[0].u32), 1636a9de470cSBruce Richardson }, 1637a9de470cSBruce Richardson { 1638a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1639a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1640a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1641a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[1].u64), 1642a9de470cSBruce Richardson }, 1643a9de470cSBruce Richardson { 1644a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1645a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1646a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1647a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[2].u32), 1648a9de470cSBruce Richardson }, 1649a9de470cSBruce Richardson { 1650a9de470cSBruce Richardson .code = (BPF_ALU | BPF_DIV | BPF_K), 1651a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1652a9de470cSBruce Richardson .imm = TEST_MUL_1, 1653a9de470cSBruce Richardson }, 1654a9de470cSBruce Richardson { 1655a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_MOD | BPF_K), 1656a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1657a9de470cSBruce Richardson .imm = TEST_MUL_2, 1658a9de470cSBruce Richardson }, 1659a9de470cSBruce Richardson { 1660a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 1661a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1662a9de470cSBruce Richardson .imm = 1, 1663a9de470cSBruce Richardson }, 1664a9de470cSBruce Richardson { 1665a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_OR | BPF_K), 1666a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1667a9de470cSBruce Richardson .imm = 1, 1668a9de470cSBruce Richardson }, 1669a9de470cSBruce Richardson { 1670a9de470cSBruce Richardson .code = (BPF_ALU | BPF_MOD | BPF_X), 1671a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1672a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1673a9de470cSBruce Richardson }, 1674a9de470cSBruce Richardson { 1675a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_DIV | BPF_X), 1676a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1677a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1678a9de470cSBruce Richardson }, 1679a9de470cSBruce Richardson { 1680a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1681a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1682a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1683a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[0].u64), 1684a9de470cSBruce Richardson }, 1685a9de470cSBruce Richardson { 1686a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1687a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1688a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1689a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[1].u64), 1690a9de470cSBruce Richardson }, 1691a9de470cSBruce Richardson { 1692a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1693a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1694a9de470cSBruce Richardson .src_reg = EBPF_REG_4, 1695a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, out[2].u64), 1696a9de470cSBruce Richardson }, 1697a9de470cSBruce Richardson /* check that we can handle division by zero gracefully. */ 1698a9de470cSBruce Richardson { 1699a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1700a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1701a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1702a9de470cSBruce Richardson .off = offsetof(struct dummy_vect8, in[3].u32), 1703a9de470cSBruce Richardson }, 1704a9de470cSBruce Richardson { 1705a9de470cSBruce Richardson .code = (BPF_ALU | BPF_DIV | BPF_X), 1706a9de470cSBruce Richardson .dst_reg = EBPF_REG_4, 1707a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1708a9de470cSBruce Richardson }, 1709a9de470cSBruce Richardson /* return 1 */ 1710a9de470cSBruce Richardson { 1711a9de470cSBruce Richardson .code = (BPF_ALU | EBPF_MOV | BPF_K), 1712a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1713a9de470cSBruce Richardson .imm = 1, 1714a9de470cSBruce Richardson }, 1715a9de470cSBruce Richardson { 1716a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1717a9de470cSBruce Richardson }, 1718a9de470cSBruce Richardson }; 1719a9de470cSBruce Richardson 1720a9de470cSBruce Richardson static int 1721a9de470cSBruce Richardson test_div1_check(uint64_t rc, const void *arg) 1722a9de470cSBruce Richardson { 1723a9de470cSBruce Richardson uint64_t r2, r3, r4; 1724a9de470cSBruce Richardson const struct dummy_vect8 *dvt; 1725a9de470cSBruce Richardson struct dummy_vect8 dve; 1726a9de470cSBruce Richardson 1727a9de470cSBruce Richardson dvt = arg; 1728a9de470cSBruce Richardson memset(&dve, 0, sizeof(dve)); 1729a9de470cSBruce Richardson 1730a9de470cSBruce Richardson r2 = dvt->in[0].u32; 1731a9de470cSBruce Richardson r3 = dvt->in[1].u64; 1732a9de470cSBruce Richardson r4 = dvt->in[2].u32; 1733a9de470cSBruce Richardson 1734a9de470cSBruce Richardson r2 = (uint32_t)r2 / TEST_MUL_1; 1735a9de470cSBruce Richardson r3 %= TEST_MUL_2; 1736a9de470cSBruce Richardson r2 |= 1; 1737a9de470cSBruce Richardson r3 |= 1; 1738a9de470cSBruce Richardson r4 = (uint32_t)(r4 % r2); 1739a9de470cSBruce Richardson r4 /= r3; 1740a9de470cSBruce Richardson 1741a9de470cSBruce Richardson dve.out[0].u64 = r2; 1742a9de470cSBruce Richardson dve.out[1].u64 = r3; 1743a9de470cSBruce Richardson dve.out[2].u64 = r4; 1744a9de470cSBruce Richardson 1745a9de470cSBruce Richardson /* 1746a9de470cSBruce Richardson * in the test prog we attempted to divide by zero. 1747a9de470cSBruce Richardson * so return value should return 0. 1748a9de470cSBruce Richardson */ 1749a9de470cSBruce Richardson return cmp_res(__func__, 0, rc, dve.out, dvt->out, sizeof(dve.out)); 1750a9de470cSBruce Richardson } 1751a9de470cSBruce Richardson 1752a9de470cSBruce Richardson /* call test-cases */ 1753a9de470cSBruce Richardson static const struct ebpf_insn test_call1_prog[] = { 1754a9de470cSBruce Richardson 1755a9de470cSBruce Richardson { 1756a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1757a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1758a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1759a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u32), 1760a9de470cSBruce Richardson }, 1761a9de470cSBruce Richardson { 1762a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1763a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1764a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1765a9de470cSBruce Richardson .off = offsetof(struct dummy_offset, u64), 1766a9de470cSBruce Richardson }, 1767a9de470cSBruce Richardson { 1768a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | BPF_W), 1769a9de470cSBruce Richardson .dst_reg = EBPF_REG_10, 1770a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1771a9de470cSBruce Richardson .off = -4, 1772a9de470cSBruce Richardson }, 1773a9de470cSBruce Richardson { 1774a9de470cSBruce Richardson .code = (BPF_STX | BPF_MEM | EBPF_DW), 1775a9de470cSBruce Richardson .dst_reg = EBPF_REG_10, 1776a9de470cSBruce Richardson .src_reg = EBPF_REG_3, 1777a9de470cSBruce Richardson .off = -16, 1778a9de470cSBruce Richardson }, 1779a9de470cSBruce Richardson { 1780a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 1781a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1782a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1783a9de470cSBruce Richardson }, 1784a9de470cSBruce Richardson { 1785a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_SUB | BPF_K), 1786a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1787a9de470cSBruce Richardson .imm = 4, 1788a9de470cSBruce Richardson }, 1789a9de470cSBruce Richardson { 1790a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 1791a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1792a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1793a9de470cSBruce Richardson }, 1794a9de470cSBruce Richardson { 1795a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_SUB | BPF_K), 1796a9de470cSBruce Richardson .dst_reg = EBPF_REG_3, 1797a9de470cSBruce Richardson .imm = 16, 1798a9de470cSBruce Richardson }, 1799a9de470cSBruce Richardson { 1800a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_CALL), 1801a9de470cSBruce Richardson .imm = 0, 1802a9de470cSBruce Richardson }, 1803a9de470cSBruce Richardson { 1804a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1805a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1806a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1807a9de470cSBruce Richardson .off = -4, 1808a9de470cSBruce Richardson }, 1809a9de470cSBruce Richardson { 1810a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1811a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1812a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1813a9de470cSBruce Richardson .off = -16 1814a9de470cSBruce Richardson }, 1815a9de470cSBruce Richardson { 1816a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 1817a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1818a9de470cSBruce Richardson .src_reg = EBPF_REG_2, 1819a9de470cSBruce Richardson }, 1820a9de470cSBruce Richardson { 1821a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1822a9de470cSBruce Richardson }, 1823a9de470cSBruce Richardson }; 1824a9de470cSBruce Richardson 1825a9de470cSBruce Richardson static void 1826a9de470cSBruce Richardson dummy_func1(const void *p, uint32_t *v32, uint64_t *v64) 1827a9de470cSBruce Richardson { 1828a9de470cSBruce Richardson const struct dummy_offset *dv; 1829a9de470cSBruce Richardson 1830a9de470cSBruce Richardson dv = p; 1831a9de470cSBruce Richardson 1832a9de470cSBruce Richardson v32[0] += dv->u16; 1833a9de470cSBruce Richardson v64[0] += dv->u8; 1834a9de470cSBruce Richardson } 1835a9de470cSBruce Richardson 1836a9de470cSBruce Richardson static int 1837a9de470cSBruce Richardson test_call1_check(uint64_t rc, const void *arg) 1838a9de470cSBruce Richardson { 1839a9de470cSBruce Richardson uint32_t v32; 1840a9de470cSBruce Richardson uint64_t v64; 1841a9de470cSBruce Richardson const struct dummy_offset *dv; 1842a9de470cSBruce Richardson 1843a9de470cSBruce Richardson dv = arg; 1844a9de470cSBruce Richardson 1845a9de470cSBruce Richardson v32 = dv->u32; 1846a9de470cSBruce Richardson v64 = dv->u64; 1847a9de470cSBruce Richardson dummy_func1(arg, &v32, &v64); 1848a9de470cSBruce Richardson v64 += v32; 1849a9de470cSBruce Richardson 1850a9de470cSBruce Richardson return cmp_res(__func__, v64, rc, dv, dv, sizeof(*dv)); 1851a9de470cSBruce Richardson } 1852a9de470cSBruce Richardson 1853a9de470cSBruce Richardson static const struct rte_bpf_xsym test_call1_xsym[] = { 1854a9de470cSBruce Richardson { 1855a9de470cSBruce Richardson .name = RTE_STR(dummy_func1), 1856a9de470cSBruce Richardson .type = RTE_BPF_XTYPE_FUNC, 1857a9de470cSBruce Richardson .func = { 1858a9de470cSBruce Richardson .val = (void *)dummy_func1, 1859a9de470cSBruce Richardson .nb_args = 3, 1860a9de470cSBruce Richardson .args = { 1861a9de470cSBruce Richardson [0] = { 1862a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 1863a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 1864a9de470cSBruce Richardson }, 1865a9de470cSBruce Richardson [1] = { 1866a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 1867a9de470cSBruce Richardson .size = sizeof(uint32_t), 1868a9de470cSBruce Richardson }, 1869a9de470cSBruce Richardson [2] = { 1870a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 1871a9de470cSBruce Richardson .size = sizeof(uint64_t), 1872a9de470cSBruce Richardson }, 1873a9de470cSBruce Richardson }, 1874a9de470cSBruce Richardson }, 1875a9de470cSBruce Richardson }, 1876a9de470cSBruce Richardson }; 1877a9de470cSBruce Richardson 1878a9de470cSBruce Richardson static const struct ebpf_insn test_call2_prog[] = { 1879a9de470cSBruce Richardson 1880a9de470cSBruce Richardson { 1881a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 1882a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1883a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1884a9de470cSBruce Richardson }, 1885a9de470cSBruce Richardson { 1886a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 1887a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1888a9de470cSBruce Richardson .imm = -(int32_t)sizeof(struct dummy_offset), 1889a9de470cSBruce Richardson }, 1890a9de470cSBruce Richardson { 1891a9de470cSBruce Richardson .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 1892a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1893a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1894a9de470cSBruce Richardson }, 1895a9de470cSBruce Richardson { 1896a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 1897a9de470cSBruce Richardson .dst_reg = EBPF_REG_2, 1898a9de470cSBruce Richardson .imm = -2 * (int32_t)sizeof(struct dummy_offset), 1899a9de470cSBruce Richardson }, 1900a9de470cSBruce Richardson { 1901a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_CALL), 1902a9de470cSBruce Richardson .imm = 0, 1903a9de470cSBruce Richardson }, 1904a9de470cSBruce Richardson { 1905a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | EBPF_DW), 1906a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1907a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1908a9de470cSBruce Richardson .off = -(int32_t)(sizeof(struct dummy_offset) - 1909a9de470cSBruce Richardson offsetof(struct dummy_offset, u64)), 1910a9de470cSBruce Richardson }, 1911a9de470cSBruce Richardson { 1912a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_W), 1913a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1914a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1915a9de470cSBruce Richardson .off = -(int32_t)(sizeof(struct dummy_offset) - 1916a9de470cSBruce Richardson offsetof(struct dummy_offset, u32)), 1917a9de470cSBruce Richardson }, 1918a9de470cSBruce Richardson { 1919a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 1920a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1921a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1922a9de470cSBruce Richardson }, 1923a9de470cSBruce Richardson { 1924a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_H), 1925a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1926a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1927a9de470cSBruce Richardson .off = -(int32_t)(2 * sizeof(struct dummy_offset) - 1928a9de470cSBruce Richardson offsetof(struct dummy_offset, u16)), 1929a9de470cSBruce Richardson }, 1930a9de470cSBruce Richardson { 1931a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 1932a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1933a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1934a9de470cSBruce Richardson }, 1935a9de470cSBruce Richardson { 1936a9de470cSBruce Richardson .code = (BPF_LDX | BPF_MEM | BPF_B), 1937a9de470cSBruce Richardson .dst_reg = EBPF_REG_1, 1938a9de470cSBruce Richardson .src_reg = EBPF_REG_10, 1939a9de470cSBruce Richardson .off = -(int32_t)(2 * sizeof(struct dummy_offset) - 1940a9de470cSBruce Richardson offsetof(struct dummy_offset, u8)), 1941a9de470cSBruce Richardson }, 1942a9de470cSBruce Richardson { 1943a9de470cSBruce Richardson .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 1944a9de470cSBruce Richardson .dst_reg = EBPF_REG_0, 1945a9de470cSBruce Richardson .src_reg = EBPF_REG_1, 1946a9de470cSBruce Richardson }, 1947a9de470cSBruce Richardson { 1948a9de470cSBruce Richardson .code = (BPF_JMP | EBPF_EXIT), 1949a9de470cSBruce Richardson }, 1950a9de470cSBruce Richardson 1951a9de470cSBruce Richardson }; 1952a9de470cSBruce Richardson 1953a9de470cSBruce Richardson static void 1954a9de470cSBruce Richardson dummy_func2(struct dummy_offset *a, struct dummy_offset *b) 1955a9de470cSBruce Richardson { 1956a9de470cSBruce Richardson uint64_t v; 1957a9de470cSBruce Richardson 1958a9de470cSBruce Richardson v = 0; 1959a9de470cSBruce Richardson a->u64 = v++; 1960a9de470cSBruce Richardson a->u32 = v++; 1961a9de470cSBruce Richardson a->u16 = v++; 1962a9de470cSBruce Richardson a->u8 = v++; 1963a9de470cSBruce Richardson b->u64 = v++; 1964a9de470cSBruce Richardson b->u32 = v++; 1965a9de470cSBruce Richardson b->u16 = v++; 1966a9de470cSBruce Richardson b->u8 = v++; 1967a9de470cSBruce Richardson } 1968a9de470cSBruce Richardson 1969a9de470cSBruce Richardson static int 1970a9de470cSBruce Richardson test_call2_check(uint64_t rc, const void *arg) 1971a9de470cSBruce Richardson { 1972a9de470cSBruce Richardson uint64_t v; 1973a9de470cSBruce Richardson struct dummy_offset a, b; 1974a9de470cSBruce Richardson 1975a9de470cSBruce Richardson RTE_SET_USED(arg); 1976a9de470cSBruce Richardson 1977a9de470cSBruce Richardson dummy_func2(&a, &b); 1978a9de470cSBruce Richardson v = a.u64 + a.u32 + b.u16 + b.u8; 1979a9de470cSBruce Richardson 198083633ba2SKonstantin Ananyev return cmp_res(__func__, v, rc, arg, arg, 0); 1981a9de470cSBruce Richardson } 1982a9de470cSBruce Richardson 1983a9de470cSBruce Richardson static const struct rte_bpf_xsym test_call2_xsym[] = { 1984a9de470cSBruce Richardson { 1985a9de470cSBruce Richardson .name = RTE_STR(dummy_func2), 1986a9de470cSBruce Richardson .type = RTE_BPF_XTYPE_FUNC, 1987a9de470cSBruce Richardson .func = { 1988a9de470cSBruce Richardson .val = (void *)dummy_func2, 1989a9de470cSBruce Richardson .nb_args = 2, 1990a9de470cSBruce Richardson .args = { 1991a9de470cSBruce Richardson [0] = { 1992a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 1993a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 1994a9de470cSBruce Richardson }, 1995a9de470cSBruce Richardson [1] = { 1996a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 1997a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 1998a9de470cSBruce Richardson }, 1999a9de470cSBruce Richardson }, 2000a9de470cSBruce Richardson }, 2001a9de470cSBruce Richardson }, 2002a9de470cSBruce Richardson }; 2003a9de470cSBruce Richardson 20047e30313fSKonstantin Ananyev static const struct ebpf_insn test_call3_prog[] = { 20057e30313fSKonstantin Ananyev 20067e30313fSKonstantin Ananyev { 20077e30313fSKonstantin Ananyev .code = (BPF_JMP | EBPF_CALL), 20087e30313fSKonstantin Ananyev .imm = 0, 20097e30313fSKonstantin Ananyev }, 20107e30313fSKonstantin Ananyev { 20117e30313fSKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | BPF_B), 20127e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_2, 20137e30313fSKonstantin Ananyev .src_reg = EBPF_REG_0, 20147e30313fSKonstantin Ananyev .off = offsetof(struct dummy_offset, u8), 20157e30313fSKonstantin Ananyev }, 20167e30313fSKonstantin Ananyev { 20177e30313fSKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | BPF_H), 20187e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_3, 20197e30313fSKonstantin Ananyev .src_reg = EBPF_REG_0, 20207e30313fSKonstantin Ananyev .off = offsetof(struct dummy_offset, u16), 20217e30313fSKonstantin Ananyev }, 20227e30313fSKonstantin Ananyev { 20237e30313fSKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | BPF_W), 20247e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_4, 20257e30313fSKonstantin Ananyev .src_reg = EBPF_REG_0, 20267e30313fSKonstantin Ananyev .off = offsetof(struct dummy_offset, u32), 20277e30313fSKonstantin Ananyev }, 20287e30313fSKonstantin Ananyev { 20297e30313fSKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | EBPF_DW), 20307e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_0, 20317e30313fSKonstantin Ananyev .src_reg = EBPF_REG_0, 20327e30313fSKonstantin Ananyev .off = offsetof(struct dummy_offset, u64), 20337e30313fSKonstantin Ananyev }, 20347e30313fSKonstantin Ananyev /* return sum */ 20357e30313fSKonstantin Ananyev { 20367e30313fSKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 20377e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_0, 20387e30313fSKonstantin Ananyev .src_reg = EBPF_REG_4, 20397e30313fSKonstantin Ananyev }, 20407e30313fSKonstantin Ananyev { 20417e30313fSKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 20427e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_0, 20437e30313fSKonstantin Ananyev .src_reg = EBPF_REG_3, 20447e30313fSKonstantin Ananyev }, 20457e30313fSKonstantin Ananyev { 20467e30313fSKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 20477e30313fSKonstantin Ananyev .dst_reg = EBPF_REG_0, 20487e30313fSKonstantin Ananyev .src_reg = EBPF_REG_2, 20497e30313fSKonstantin Ananyev }, 20507e30313fSKonstantin Ananyev { 20517e30313fSKonstantin Ananyev .code = (BPF_JMP | EBPF_EXIT), 20527e30313fSKonstantin Ananyev }, 20537e30313fSKonstantin Ananyev }; 20547e30313fSKonstantin Ananyev 20557e30313fSKonstantin Ananyev static const struct dummy_offset * 20567e30313fSKonstantin Ananyev dummy_func3(const struct dummy_vect8 *p) 20577e30313fSKonstantin Ananyev { 20587e30313fSKonstantin Ananyev return &p->in[RTE_DIM(p->in) - 1]; 20597e30313fSKonstantin Ananyev } 20607e30313fSKonstantin Ananyev 20617e30313fSKonstantin Ananyev static void 20627e30313fSKonstantin Ananyev test_call3_prepare(void *arg) 20637e30313fSKonstantin Ananyev { 20647e30313fSKonstantin Ananyev struct dummy_vect8 *pv; 20657e30313fSKonstantin Ananyev struct dummy_offset *df; 20667e30313fSKonstantin Ananyev 20677e30313fSKonstantin Ananyev pv = arg; 20687e30313fSKonstantin Ananyev df = (struct dummy_offset *)(uintptr_t)dummy_func3(pv); 20697e30313fSKonstantin Ananyev 20707e30313fSKonstantin Ananyev memset(pv, 0, sizeof(*pv)); 20717e30313fSKonstantin Ananyev df->u64 = (int32_t)TEST_FILL_1; 20727e30313fSKonstantin Ananyev df->u32 = df->u64; 20737e30313fSKonstantin Ananyev df->u16 = df->u64; 20747e30313fSKonstantin Ananyev df->u8 = df->u64; 20757e30313fSKonstantin Ananyev } 20767e30313fSKonstantin Ananyev 20777e30313fSKonstantin Ananyev static int 20787e30313fSKonstantin Ananyev test_call3_check(uint64_t rc, const void *arg) 20797e30313fSKonstantin Ananyev { 20807e30313fSKonstantin Ananyev uint64_t v; 20817e30313fSKonstantin Ananyev const struct dummy_vect8 *pv; 20827e30313fSKonstantin Ananyev const struct dummy_offset *dft; 20837e30313fSKonstantin Ananyev 20847e30313fSKonstantin Ananyev pv = arg; 20857e30313fSKonstantin Ananyev dft = dummy_func3(pv); 20867e30313fSKonstantin Ananyev 20877e30313fSKonstantin Ananyev v = dft->u64; 20887e30313fSKonstantin Ananyev v += dft->u32; 20897e30313fSKonstantin Ananyev v += dft->u16; 20907e30313fSKonstantin Ananyev v += dft->u8; 20917e30313fSKonstantin Ananyev 20927e30313fSKonstantin Ananyev return cmp_res(__func__, v, rc, pv, pv, sizeof(*pv)); 20937e30313fSKonstantin Ananyev } 20947e30313fSKonstantin Ananyev 20957e30313fSKonstantin Ananyev static const struct rte_bpf_xsym test_call3_xsym[] = { 20967e30313fSKonstantin Ananyev { 20977e30313fSKonstantin Ananyev .name = RTE_STR(dummy_func3), 20987e30313fSKonstantin Ananyev .type = RTE_BPF_XTYPE_FUNC, 20997e30313fSKonstantin Ananyev .func = { 21007e30313fSKonstantin Ananyev .val = (void *)dummy_func3, 21017e30313fSKonstantin Ananyev .nb_args = 1, 21027e30313fSKonstantin Ananyev .args = { 21037e30313fSKonstantin Ananyev [0] = { 21047e30313fSKonstantin Ananyev .type = RTE_BPF_ARG_PTR, 21057e30313fSKonstantin Ananyev .size = sizeof(struct dummy_vect8), 21067e30313fSKonstantin Ananyev }, 21077e30313fSKonstantin Ananyev }, 21087e30313fSKonstantin Ananyev .ret = { 21097e30313fSKonstantin Ananyev .type = RTE_BPF_ARG_PTR, 21107e30313fSKonstantin Ananyev .size = sizeof(struct dummy_offset), 21117e30313fSKonstantin Ananyev }, 21127e30313fSKonstantin Ananyev }, 21137e30313fSKonstantin Ananyev }, 21147e30313fSKonstantin Ananyev }; 21157e30313fSKonstantin Ananyev 2116cddd8795SHarman Kalra /* Test for stack corruption in multiple function calls */ 2117cddd8795SHarman Kalra static const struct ebpf_insn test_call4_prog[] = { 2118cddd8795SHarman Kalra { 2119cddd8795SHarman Kalra .code = (BPF_ST | BPF_MEM | BPF_B), 2120cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2121cddd8795SHarman Kalra .off = -4, 2122cddd8795SHarman Kalra .imm = 1, 2123cddd8795SHarman Kalra }, 2124cddd8795SHarman Kalra { 2125cddd8795SHarman Kalra .code = (BPF_ST | BPF_MEM | BPF_B), 2126cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2127cddd8795SHarman Kalra .off = -3, 2128cddd8795SHarman Kalra .imm = 2, 2129cddd8795SHarman Kalra }, 2130cddd8795SHarman Kalra { 2131cddd8795SHarman Kalra .code = (BPF_ST | BPF_MEM | BPF_B), 2132cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2133cddd8795SHarman Kalra .off = -2, 2134cddd8795SHarman Kalra .imm = 3, 2135cddd8795SHarman Kalra }, 2136cddd8795SHarman Kalra { 2137cddd8795SHarman Kalra .code = (BPF_ST | BPF_MEM | BPF_B), 2138cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2139cddd8795SHarman Kalra .off = -1, 2140cddd8795SHarman Kalra .imm = 4, 2141cddd8795SHarman Kalra }, 2142cddd8795SHarman Kalra { 2143cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2144cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2145cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2146cddd8795SHarman Kalra }, 2147cddd8795SHarman Kalra { 2148cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 2149cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 2150cddd8795SHarman Kalra .imm = 4, 2151cddd8795SHarman Kalra }, 2152cddd8795SHarman Kalra { 2153cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_SUB | BPF_X), 2154cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2155cddd8795SHarman Kalra .src_reg = EBPF_REG_2, 2156cddd8795SHarman Kalra }, 2157cddd8795SHarman Kalra { 2158cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_CALL), 2159cddd8795SHarman Kalra .imm = 0, 2160cddd8795SHarman Kalra }, 2161cddd8795SHarman Kalra { 2162cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_B), 2163cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2164cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2165cddd8795SHarman Kalra .off = -4, 2166cddd8795SHarman Kalra }, 2167cddd8795SHarman Kalra { 2168cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_B), 2169cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 2170cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2171cddd8795SHarman Kalra .off = -3, 2172cddd8795SHarman Kalra }, 2173cddd8795SHarman Kalra { 2174cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_B), 2175cddd8795SHarman Kalra .dst_reg = EBPF_REG_3, 2176cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2177cddd8795SHarman Kalra .off = -2, 2178cddd8795SHarman Kalra }, 2179cddd8795SHarman Kalra { 2180cddd8795SHarman Kalra .code = (BPF_LDX | BPF_MEM | BPF_B), 2181cddd8795SHarman Kalra .dst_reg = EBPF_REG_4, 2182cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2183cddd8795SHarman Kalra .off = -1, 2184cddd8795SHarman Kalra }, 2185cddd8795SHarman Kalra { 2186cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_CALL), 2187cddd8795SHarman Kalra .imm = 1, 2188cddd8795SHarman Kalra }, 2189cddd8795SHarman Kalra { 2190cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_XOR | BPF_K), 2191cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 2192cddd8795SHarman Kalra .imm = TEST_MEMFROB, 2193cddd8795SHarman Kalra }, 2194cddd8795SHarman Kalra { 2195cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_EXIT), 2196cddd8795SHarman Kalra }, 2197cddd8795SHarman Kalra }; 2198cddd8795SHarman Kalra 2199cddd8795SHarman Kalra /* Gathering the bytes together */ 2200cddd8795SHarman Kalra static uint32_t 2201cddd8795SHarman Kalra dummy_func4_1(uint8_t a, uint8_t b, uint8_t c, uint8_t d) 2202cddd8795SHarman Kalra { 2203cddd8795SHarman Kalra return (a << 24) | (b << 16) | (c << 8) | (d << 0); 2204cddd8795SHarman Kalra } 2205cddd8795SHarman Kalra 2206cddd8795SHarman Kalra /* Implementation of memfrob */ 2207cddd8795SHarman Kalra static uint32_t 2208cddd8795SHarman Kalra dummy_func4_0(uint32_t *s, uint8_t n) 2209cddd8795SHarman Kalra { 2210cddd8795SHarman Kalra char *p = (char *) s; 2211cddd8795SHarman Kalra while (n-- > 0) 2212cddd8795SHarman Kalra *p++ ^= 42; 2213cddd8795SHarman Kalra return *s; 2214cddd8795SHarman Kalra } 2215cddd8795SHarman Kalra 2216cddd8795SHarman Kalra 2217cddd8795SHarman Kalra static int 2218cddd8795SHarman Kalra test_call4_check(uint64_t rc, const void *arg) 2219cddd8795SHarman Kalra { 2220cddd8795SHarman Kalra uint8_t a[4] = {1, 2, 3, 4}; 2221cddd8795SHarman Kalra uint32_t s, v = 0; 2222cddd8795SHarman Kalra 2223cddd8795SHarman Kalra RTE_SET_USED(arg); 2224cddd8795SHarman Kalra 2225cddd8795SHarman Kalra s = dummy_func4_0((uint32_t *)a, 4); 2226cddd8795SHarman Kalra 2227cddd8795SHarman Kalra s = dummy_func4_1(a[0], a[1], a[2], a[3]); 2228cddd8795SHarman Kalra 2229cddd8795SHarman Kalra v = s ^ TEST_MEMFROB; 2230cddd8795SHarman Kalra 2231cddd8795SHarman Kalra return cmp_res(__func__, v, rc, &v, &rc, sizeof(v)); 2232cddd8795SHarman Kalra } 2233cddd8795SHarman Kalra 2234cddd8795SHarman Kalra static const struct rte_bpf_xsym test_call4_xsym[] = { 2235cddd8795SHarman Kalra [0] = { 2236cddd8795SHarman Kalra .name = RTE_STR(dummy_func4_0), 2237cddd8795SHarman Kalra .type = RTE_BPF_XTYPE_FUNC, 2238cddd8795SHarman Kalra .func = { 2239cddd8795SHarman Kalra .val = (void *)dummy_func4_0, 2240cddd8795SHarman Kalra .nb_args = 2, 2241cddd8795SHarman Kalra .args = { 2242cddd8795SHarman Kalra [0] = { 2243cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 2244cddd8795SHarman Kalra .size = 4 * sizeof(uint8_t), 2245cddd8795SHarman Kalra }, 2246cddd8795SHarman Kalra [1] = { 2247cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2248cddd8795SHarman Kalra .size = sizeof(uint8_t), 2249cddd8795SHarman Kalra }, 2250cddd8795SHarman Kalra }, 2251cddd8795SHarman Kalra .ret = { 2252cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2253cddd8795SHarman Kalra .size = sizeof(uint32_t), 2254cddd8795SHarman Kalra }, 2255cddd8795SHarman Kalra }, 2256cddd8795SHarman Kalra }, 2257cddd8795SHarman Kalra [1] = { 2258cddd8795SHarman Kalra .name = RTE_STR(dummy_func4_1), 2259cddd8795SHarman Kalra .type = RTE_BPF_XTYPE_FUNC, 2260cddd8795SHarman Kalra .func = { 2261cddd8795SHarman Kalra .val = (void *)dummy_func4_1, 2262cddd8795SHarman Kalra .nb_args = 4, 2263cddd8795SHarman Kalra .args = { 2264cddd8795SHarman Kalra [0] = { 2265cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2266cddd8795SHarman Kalra .size = sizeof(uint8_t), 2267cddd8795SHarman Kalra }, 2268cddd8795SHarman Kalra [1] = { 2269cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2270cddd8795SHarman Kalra .size = sizeof(uint8_t), 2271cddd8795SHarman Kalra }, 2272cddd8795SHarman Kalra [2] = { 2273cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2274cddd8795SHarman Kalra .size = sizeof(uint8_t), 2275cddd8795SHarman Kalra }, 2276cddd8795SHarman Kalra [3] = { 2277cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2278cddd8795SHarman Kalra .size = sizeof(uint8_t), 2279cddd8795SHarman Kalra }, 2280cddd8795SHarman Kalra }, 2281cddd8795SHarman Kalra .ret = { 2282cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2283cddd8795SHarman Kalra .size = sizeof(uint32_t), 2284cddd8795SHarman Kalra }, 2285cddd8795SHarman Kalra }, 2286cddd8795SHarman Kalra }, 2287cddd8795SHarman Kalra }; 2288cddd8795SHarman Kalra 2289cddd8795SHarman Kalra /* string compare test case */ 2290cddd8795SHarman Kalra static const struct ebpf_insn test_call5_prog[] = { 2291cddd8795SHarman Kalra 2292cddd8795SHarman Kalra [0] = { 2293cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 2294cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2295cddd8795SHarman Kalra .imm = STRING_GEEK, 2296cddd8795SHarman Kalra }, 2297cddd8795SHarman Kalra [1] = { 2298cddd8795SHarman Kalra .code = (BPF_STX | BPF_MEM | BPF_W), 2299cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2300cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 2301cddd8795SHarman Kalra .off = -8, 2302cddd8795SHarman Kalra }, 2303cddd8795SHarman Kalra [2] = { 2304cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 2305cddd8795SHarman Kalra .dst_reg = EBPF_REG_6, 2306cddd8795SHarman Kalra .imm = 0, 2307cddd8795SHarman Kalra }, 2308cddd8795SHarman Kalra [3] = { 2309cddd8795SHarman Kalra .code = (BPF_STX | BPF_MEM | BPF_B), 2310cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2311cddd8795SHarman Kalra .src_reg = EBPF_REG_6, 2312cddd8795SHarman Kalra .off = -4, 2313cddd8795SHarman Kalra }, 2314cddd8795SHarman Kalra [4] = { 2315cddd8795SHarman Kalra .code = (BPF_STX | BPF_MEM | BPF_W), 2316cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2317cddd8795SHarman Kalra .src_reg = EBPF_REG_6, 2318cddd8795SHarman Kalra .off = -12, 2319cddd8795SHarman Kalra }, 2320cddd8795SHarman Kalra [5] = { 2321cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 2322cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2323cddd8795SHarman Kalra .imm = STRING_WEEK, 2324cddd8795SHarman Kalra }, 2325cddd8795SHarman Kalra [6] = { 2326cddd8795SHarman Kalra .code = (BPF_STX | BPF_MEM | BPF_W), 2327cddd8795SHarman Kalra .dst_reg = EBPF_REG_10, 2328cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 2329cddd8795SHarman Kalra .off = -16, 2330cddd8795SHarman Kalra }, 2331cddd8795SHarman Kalra [7] = { 2332cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2333cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2334cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2335cddd8795SHarman Kalra }, 2336cddd8795SHarman Kalra [8] = { 2337cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 2338cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2339cddd8795SHarman Kalra .imm = -8, 2340cddd8795SHarman Kalra }, 2341cddd8795SHarman Kalra [9] = { 2342cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2343cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 2344cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 2345cddd8795SHarman Kalra }, 2346cddd8795SHarman Kalra [10] = { 2347cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_CALL), 2348cddd8795SHarman Kalra .imm = 0, 2349cddd8795SHarman Kalra }, 2350cddd8795SHarman Kalra [11] = { 2351cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2352cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2353cddd8795SHarman Kalra .src_reg = EBPF_REG_0, 2354cddd8795SHarman Kalra }, 2355cddd8795SHarman Kalra [12] = { 2356cddd8795SHarman Kalra .code = (BPF_ALU | EBPF_MOV | BPF_K), 2357cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 2358cddd8795SHarman Kalra .imm = -1, 2359cddd8795SHarman Kalra }, 2360cddd8795SHarman Kalra [13] = { 2361cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_LSH | BPF_K), 2362cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2363cddd8795SHarman Kalra .imm = 0x20, 2364cddd8795SHarman Kalra }, 2365cddd8795SHarman Kalra [14] = { 2366cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_RSH | BPF_K), 2367cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2368cddd8795SHarman Kalra .imm = 0x20, 2369cddd8795SHarman Kalra }, 2370cddd8795SHarman Kalra [15] = { 2371cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_JNE | BPF_K), 2372cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2373cddd8795SHarman Kalra .off = 11, 2374cddd8795SHarman Kalra .imm = 0, 2375cddd8795SHarman Kalra }, 2376cddd8795SHarman Kalra [16] = { 2377cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2378cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2379cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2380cddd8795SHarman Kalra }, 2381cddd8795SHarman Kalra [17] = { 2382cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 2383cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2384cddd8795SHarman Kalra .imm = -8, 2385cddd8795SHarman Kalra }, 2386cddd8795SHarman Kalra [18] = { 2387cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2388cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 2389cddd8795SHarman Kalra .src_reg = EBPF_REG_10, 2390cddd8795SHarman Kalra }, 2391cddd8795SHarman Kalra [19] = { 2392cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_ADD | BPF_K), 2393cddd8795SHarman Kalra .dst_reg = EBPF_REG_2, 2394cddd8795SHarman Kalra .imm = -16, 2395cddd8795SHarman Kalra }, 2396cddd8795SHarman Kalra [20] = { 2397cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_CALL), 2398cddd8795SHarman Kalra .imm = 0, 2399cddd8795SHarman Kalra }, 2400cddd8795SHarman Kalra [21] = { 2401cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2402cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2403cddd8795SHarman Kalra .src_reg = EBPF_REG_0, 2404cddd8795SHarman Kalra }, 2405cddd8795SHarman Kalra [22] = { 2406cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_LSH | BPF_K), 2407cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2408cddd8795SHarman Kalra .imm = 0x20, 2409cddd8795SHarman Kalra }, 2410cddd8795SHarman Kalra [23] = { 2411cddd8795SHarman Kalra .code = (EBPF_ALU64 | BPF_RSH | BPF_K), 2412cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2413cddd8795SHarman Kalra .imm = 0x20, 2414cddd8795SHarman Kalra }, 2415cddd8795SHarman Kalra [24] = { 2416cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2417cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 2418cddd8795SHarman Kalra .src_reg = EBPF_REG_1, 2419cddd8795SHarman Kalra }, 2420cddd8795SHarman Kalra [25] = { 2421cddd8795SHarman Kalra .code = (BPF_JMP | BPF_JEQ | BPF_X), 2422cddd8795SHarman Kalra .dst_reg = EBPF_REG_1, 2423cddd8795SHarman Kalra .src_reg = EBPF_REG_6, 2424cddd8795SHarman Kalra .off = 1, 2425cddd8795SHarman Kalra }, 2426cddd8795SHarman Kalra [26] = { 2427cddd8795SHarman Kalra .code = (EBPF_ALU64 | EBPF_MOV | BPF_K), 2428cddd8795SHarman Kalra .dst_reg = EBPF_REG_0, 2429cddd8795SHarman Kalra .imm = 0, 2430cddd8795SHarman Kalra }, 2431cddd8795SHarman Kalra [27] = { 2432cddd8795SHarman Kalra .code = (BPF_JMP | EBPF_EXIT), 2433cddd8795SHarman Kalra }, 2434cddd8795SHarman Kalra }; 2435cddd8795SHarman Kalra 24364a6672c2SStephen Hemminger /* String comparison implementation, return 0 if equal else difference */ 2437cddd8795SHarman Kalra static uint32_t 2438cddd8795SHarman Kalra dummy_func5(const char *s1, const char *s2) 2439cddd8795SHarman Kalra { 2440cddd8795SHarman Kalra while (*s1 && (*s1 == *s2)) { 2441cddd8795SHarman Kalra s1++; 2442cddd8795SHarman Kalra s2++; 2443cddd8795SHarman Kalra } 2444cddd8795SHarman Kalra return *(const unsigned char *)s1 - *(const unsigned char *)s2; 2445cddd8795SHarman Kalra } 2446cddd8795SHarman Kalra 2447cddd8795SHarman Kalra static int 2448cddd8795SHarman Kalra test_call5_check(uint64_t rc, const void *arg) 2449cddd8795SHarman Kalra { 2450cddd8795SHarman Kalra char a[] = "geek"; 2451cddd8795SHarman Kalra char b[] = "week"; 2452cddd8795SHarman Kalra uint32_t v; 2453cddd8795SHarman Kalra 2454cddd8795SHarman Kalra RTE_SET_USED(arg); 2455cddd8795SHarman Kalra 2456cddd8795SHarman Kalra v = dummy_func5(a, a); 2457cddd8795SHarman Kalra if (v != 0) { 2458cddd8795SHarman Kalra v = -1; 2459cddd8795SHarman Kalra goto fail; 2460cddd8795SHarman Kalra } 2461cddd8795SHarman Kalra 2462cddd8795SHarman Kalra v = dummy_func5(a, b); 2463cddd8795SHarman Kalra if (v == 0) 2464cddd8795SHarman Kalra goto fail; 2465cddd8795SHarman Kalra 2466cddd8795SHarman Kalra v = 0; 2467cddd8795SHarman Kalra 2468cddd8795SHarman Kalra fail: 2469cddd8795SHarman Kalra return cmp_res(__func__, v, rc, &v, &rc, sizeof(v)); 2470cddd8795SHarman Kalra } 2471cddd8795SHarman Kalra 2472cddd8795SHarman Kalra static const struct rte_bpf_xsym test_call5_xsym[] = { 2473cddd8795SHarman Kalra [0] = { 2474cddd8795SHarman Kalra .name = RTE_STR(dummy_func5), 2475cddd8795SHarman Kalra .type = RTE_BPF_XTYPE_FUNC, 2476cddd8795SHarman Kalra .func = { 2477cddd8795SHarman Kalra .val = (void *)dummy_func5, 2478cddd8795SHarman Kalra .nb_args = 2, 2479cddd8795SHarman Kalra .args = { 2480cddd8795SHarman Kalra [0] = { 2481cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 2482cddd8795SHarman Kalra .size = sizeof(char), 2483cddd8795SHarman Kalra }, 2484cddd8795SHarman Kalra [1] = { 2485cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 2486cddd8795SHarman Kalra .size = sizeof(char), 2487cddd8795SHarman Kalra }, 2488cddd8795SHarman Kalra }, 2489cddd8795SHarman Kalra .ret = { 2490cddd8795SHarman Kalra .type = RTE_BPF_ARG_RAW, 2491cddd8795SHarman Kalra .size = sizeof(uint32_t), 2492cddd8795SHarman Kalra }, 2493cddd8795SHarman Kalra }, 2494cddd8795SHarman Kalra }, 2495cddd8795SHarman Kalra }; 2496cddd8795SHarman Kalra 2497b901d928SKonstantin Ananyev /* load mbuf (BPF_ABS/BPF_IND) test-cases */ 2498b901d928SKonstantin Ananyev static const struct ebpf_insn test_ld_mbuf1_prog[] = { 2499b901d928SKonstantin Ananyev 2500b901d928SKonstantin Ananyev /* BPF_ABS/BPF_IND implicitly expect mbuf ptr in R6 */ 2501b901d928SKonstantin Ananyev { 2502b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2503b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_6, 2504b901d928SKonstantin Ananyev .src_reg = EBPF_REG_1, 2505b901d928SKonstantin Ananyev }, 2506b901d928SKonstantin Ananyev /* load IPv4 version and IHL */ 2507b901d928SKonstantin Ananyev { 2508b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_B), 2509b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, version_ihl), 2510b901d928SKonstantin Ananyev }, 2511b901d928SKonstantin Ananyev /* check IP version */ 2512b901d928SKonstantin Ananyev { 2513b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2514b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2515b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2516b901d928SKonstantin Ananyev }, 2517b901d928SKonstantin Ananyev { 2518b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 2519b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2520b901d928SKonstantin Ananyev .imm = 0xf0, 2521b901d928SKonstantin Ananyev }, 2522b901d928SKonstantin Ananyev { 2523b901d928SKonstantin Ananyev .code = (BPF_JMP | BPF_JEQ | BPF_K), 2524b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2525b901d928SKonstantin Ananyev .imm = IPVERSION << 4, 2526b901d928SKonstantin Ananyev .off = 2, 2527b901d928SKonstantin Ananyev }, 2528b901d928SKonstantin Ananyev /* invalid IP version, return 0 */ 2529b901d928SKonstantin Ananyev { 2530b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_XOR | BPF_X), 2531b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2532b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2533b901d928SKonstantin Ananyev }, 2534b901d928SKonstantin Ananyev { 2535b901d928SKonstantin Ananyev .code = (BPF_JMP | EBPF_EXIT), 2536b901d928SKonstantin Ananyev }, 2537b901d928SKonstantin Ananyev /* load 3-rd byte of IP data */ 2538b901d928SKonstantin Ananyev { 2539b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 2540b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2541b901d928SKonstantin Ananyev .imm = RTE_IPV4_HDR_IHL_MASK, 2542b901d928SKonstantin Ananyev }, 2543b901d928SKonstantin Ananyev { 2544b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_LSH | BPF_K), 2545b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2546b901d928SKonstantin Ananyev .imm = 2, 2547b901d928SKonstantin Ananyev }, 2548b901d928SKonstantin Ananyev { 2549b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_B), 2550b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2551b901d928SKonstantin Ananyev .imm = 3, 2552b901d928SKonstantin Ananyev }, 2553b901d928SKonstantin Ananyev { 2554b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2555b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_7, 2556b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2557b901d928SKonstantin Ananyev }, 2558b901d928SKonstantin Ananyev /* load IPv4 src addr */ 2559b901d928SKonstantin Ananyev { 2560b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_W), 2561b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, src_addr), 2562b901d928SKonstantin Ananyev }, 2563b901d928SKonstantin Ananyev { 2564b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2565b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_7, 2566b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2567b901d928SKonstantin Ananyev }, 2568b901d928SKonstantin Ananyev /* load IPv4 total length */ 2569b901d928SKonstantin Ananyev { 2570b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_H), 2571b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, total_length), 2572b901d928SKonstantin Ananyev }, 2573b901d928SKonstantin Ananyev { 2574b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2575b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_8, 2576b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2577b901d928SKonstantin Ananyev }, 2578b901d928SKonstantin Ananyev /* load last 4 bytes of IP data */ 2579b901d928SKonstantin Ananyev { 2580b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_W), 2581b901d928SKonstantin Ananyev .src_reg = EBPF_REG_8, 2582b901d928SKonstantin Ananyev .imm = -(int32_t)sizeof(uint32_t), 2583b901d928SKonstantin Ananyev }, 2584b901d928SKonstantin Ananyev { 2585b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2586b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_7, 2587b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2588b901d928SKonstantin Ananyev }, 2589b901d928SKonstantin Ananyev /* load 2 bytes from the middle of IP data */ 2590b901d928SKonstantin Ananyev { 2591b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_RSH | BPF_K), 2592b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_8, 2593b901d928SKonstantin Ananyev .imm = 1, 2594b901d928SKonstantin Ananyev }, 2595b901d928SKonstantin Ananyev { 2596b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_H), 2597b901d928SKonstantin Ananyev .src_reg = EBPF_REG_8, 2598b901d928SKonstantin Ananyev }, 2599b901d928SKonstantin Ananyev { 2600b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2601b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2602b901d928SKonstantin Ananyev .src_reg = EBPF_REG_7, 2603b901d928SKonstantin Ananyev }, 2604b901d928SKonstantin Ananyev { 2605b901d928SKonstantin Ananyev .code = (BPF_JMP | EBPF_EXIT), 2606b901d928SKonstantin Ananyev }, 2607b901d928SKonstantin Ananyev }; 2608b901d928SKonstantin Ananyev 2609b901d928SKonstantin Ananyev static void 2610b901d928SKonstantin Ananyev dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len, 2611b901d928SKonstantin Ananyev uint32_t data_len) 2612b901d928SKonstantin Ananyev { 2613b901d928SKonstantin Ananyev uint32_t i; 2614b901d928SKonstantin Ananyev uint8_t *db; 2615b901d928SKonstantin Ananyev 2616b901d928SKonstantin Ananyev mb->buf_addr = buf; 2617e811e2d7SShijith Thotton rte_mbuf_iova_set(mb, (uintptr_t)buf); 2618b901d928SKonstantin Ananyev mb->buf_len = buf_len; 2619b901d928SKonstantin Ananyev rte_mbuf_refcnt_set(mb, 1); 2620b901d928SKonstantin Ananyev 2621b901d928SKonstantin Ananyev /* set pool pointer to dummy value, test doesn't use it */ 2622b901d928SKonstantin Ananyev mb->pool = (void *)buf; 2623b901d928SKonstantin Ananyev 2624b901d928SKonstantin Ananyev rte_pktmbuf_reset(mb); 2625b901d928SKonstantin Ananyev db = (uint8_t *)rte_pktmbuf_append(mb, data_len); 2626b901d928SKonstantin Ananyev 2627b901d928SKonstantin Ananyev for (i = 0; i != data_len; i++) 2628b901d928SKonstantin Ananyev db[i] = i; 2629b901d928SKonstantin Ananyev } 2630b901d928SKonstantin Ananyev 2631b901d928SKonstantin Ananyev static void 2632b901d928SKonstantin Ananyev test_ld_mbuf1_prepare(void *arg) 2633b901d928SKonstantin Ananyev { 2634b901d928SKonstantin Ananyev struct dummy_mbuf *dm; 2635b901d928SKonstantin Ananyev struct rte_ipv4_hdr *ph; 2636b901d928SKonstantin Ananyev 2637b901d928SKonstantin Ananyev const uint32_t plen = 400; 2638b901d928SKonstantin Ananyev const struct rte_ipv4_hdr iph = { 2639b901d928SKonstantin Ananyev .version_ihl = RTE_IPV4_VHL_DEF, 2640b901d928SKonstantin Ananyev .total_length = rte_cpu_to_be_16(plen), 2641b901d928SKonstantin Ananyev .time_to_live = IPDEFTTL, 2642b901d928SKonstantin Ananyev .next_proto_id = IPPROTO_RAW, 2643b901d928SKonstantin Ananyev .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK), 2644b901d928SKonstantin Ananyev .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST), 2645b901d928SKonstantin Ananyev }; 2646b901d928SKonstantin Ananyev 2647b901d928SKonstantin Ananyev dm = arg; 2648b901d928SKonstantin Ananyev memset(dm, 0, sizeof(*dm)); 2649b901d928SKonstantin Ananyev 2650b901d928SKonstantin Ananyev dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]), 2651b901d928SKonstantin Ananyev plen / 2 + 1); 2652b901d928SKonstantin Ananyev dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[0]), 2653b901d928SKonstantin Ananyev plen / 2 - 1); 2654b901d928SKonstantin Ananyev 2655b901d928SKonstantin Ananyev rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]); 2656b901d928SKonstantin Ananyev 2657b901d928SKonstantin Ananyev ph = rte_pktmbuf_mtod(dm->mb, typeof(ph)); 2658b901d928SKonstantin Ananyev memcpy(ph, &iph, sizeof(iph)); 2659b901d928SKonstantin Ananyev } 2660b901d928SKonstantin Ananyev 2661b901d928SKonstantin Ananyev static uint64_t 2662b901d928SKonstantin Ananyev test_ld_mbuf1(const struct rte_mbuf *pkt) 2663b901d928SKonstantin Ananyev { 2664b901d928SKonstantin Ananyev uint64_t n, v; 2665b901d928SKonstantin Ananyev const uint8_t *p8; 2666b901d928SKonstantin Ananyev const uint16_t *p16; 2667b901d928SKonstantin Ananyev const uint32_t *p32; 2668b901d928SKonstantin Ananyev struct dummy_offset dof; 2669b901d928SKonstantin Ananyev 2670b901d928SKonstantin Ananyev /* load IPv4 version and IHL */ 2671b901d928SKonstantin Ananyev p8 = rte_pktmbuf_read(pkt, 2672b901d928SKonstantin Ananyev offsetof(struct rte_ipv4_hdr, version_ihl), sizeof(*p8), 2673b901d928SKonstantin Ananyev &dof); 2674b901d928SKonstantin Ananyev if (p8 == NULL) 2675b901d928SKonstantin Ananyev return 0; 2676b901d928SKonstantin Ananyev 2677b901d928SKonstantin Ananyev /* check IP version */ 2678b901d928SKonstantin Ananyev if ((p8[0] & 0xf0) != IPVERSION << 4) 2679b901d928SKonstantin Ananyev return 0; 2680b901d928SKonstantin Ananyev 2681b901d928SKonstantin Ananyev n = (p8[0] & RTE_IPV4_HDR_IHL_MASK) * RTE_IPV4_IHL_MULTIPLIER; 2682b901d928SKonstantin Ananyev 2683b901d928SKonstantin Ananyev /* load 3-rd byte of IP data */ 2684b901d928SKonstantin Ananyev p8 = rte_pktmbuf_read(pkt, n + 3, sizeof(*p8), &dof); 2685b901d928SKonstantin Ananyev if (p8 == NULL) 2686b901d928SKonstantin Ananyev return 0; 2687b901d928SKonstantin Ananyev 2688b901d928SKonstantin Ananyev v = p8[0]; 2689b901d928SKonstantin Ananyev 2690b901d928SKonstantin Ananyev /* load IPv4 src addr */ 2691b901d928SKonstantin Ananyev p32 = rte_pktmbuf_read(pkt, 2692b901d928SKonstantin Ananyev offsetof(struct rte_ipv4_hdr, src_addr), sizeof(*p32), 2693b901d928SKonstantin Ananyev &dof); 2694b901d928SKonstantin Ananyev if (p32 == NULL) 2695b901d928SKonstantin Ananyev return 0; 2696b901d928SKonstantin Ananyev 2697b901d928SKonstantin Ananyev v += rte_be_to_cpu_32(p32[0]); 2698b901d928SKonstantin Ananyev 2699b901d928SKonstantin Ananyev /* load IPv4 total length */ 2700b901d928SKonstantin Ananyev p16 = rte_pktmbuf_read(pkt, 2701b901d928SKonstantin Ananyev offsetof(struct rte_ipv4_hdr, total_length), sizeof(*p16), 2702b901d928SKonstantin Ananyev &dof); 2703b901d928SKonstantin Ananyev if (p16 == NULL) 2704b901d928SKonstantin Ananyev return 0; 2705b901d928SKonstantin Ananyev 2706b901d928SKonstantin Ananyev n = rte_be_to_cpu_16(p16[0]); 2707b901d928SKonstantin Ananyev 2708b901d928SKonstantin Ananyev /* load last 4 bytes of IP data */ 2709b901d928SKonstantin Ananyev p32 = rte_pktmbuf_read(pkt, n - sizeof(*p32), sizeof(*p32), &dof); 2710b901d928SKonstantin Ananyev if (p32 == NULL) 2711b901d928SKonstantin Ananyev return 0; 2712b901d928SKonstantin Ananyev 2713b901d928SKonstantin Ananyev v += rte_be_to_cpu_32(p32[0]); 2714b901d928SKonstantin Ananyev 2715b901d928SKonstantin Ananyev /* load 2 bytes from the middle of IP data */ 2716b901d928SKonstantin Ananyev p16 = rte_pktmbuf_read(pkt, n / 2, sizeof(*p16), &dof); 2717b901d928SKonstantin Ananyev if (p16 == NULL) 2718b901d928SKonstantin Ananyev return 0; 2719b901d928SKonstantin Ananyev 2720b901d928SKonstantin Ananyev v += rte_be_to_cpu_16(p16[0]); 2721b901d928SKonstantin Ananyev return v; 2722b901d928SKonstantin Ananyev } 2723b901d928SKonstantin Ananyev 2724b901d928SKonstantin Ananyev static int 2725b901d928SKonstantin Ananyev test_ld_mbuf1_check(uint64_t rc, const void *arg) 2726b901d928SKonstantin Ananyev { 2727b901d928SKonstantin Ananyev const struct dummy_mbuf *dm; 2728b901d928SKonstantin Ananyev uint64_t v; 2729b901d928SKonstantin Ananyev 2730b901d928SKonstantin Ananyev dm = arg; 2731b901d928SKonstantin Ananyev v = test_ld_mbuf1(dm->mb); 2732b901d928SKonstantin Ananyev return cmp_res(__func__, v, rc, arg, arg, 0); 2733b901d928SKonstantin Ananyev } 2734b901d928SKonstantin Ananyev 2735b901d928SKonstantin Ananyev /* 27367be78d02SJosh Soref * same as ld_mbuf1, but then truncate the mbuf by 1B, 2737b901d928SKonstantin Ananyev * so load of last 4B fail. 2738b901d928SKonstantin Ananyev */ 2739b901d928SKonstantin Ananyev static void 2740b901d928SKonstantin Ananyev test_ld_mbuf2_prepare(void *arg) 2741b901d928SKonstantin Ananyev { 2742b901d928SKonstantin Ananyev struct dummy_mbuf *dm; 2743b901d928SKonstantin Ananyev 2744b901d928SKonstantin Ananyev test_ld_mbuf1_prepare(arg); 2745b901d928SKonstantin Ananyev dm = arg; 2746b901d928SKonstantin Ananyev rte_pktmbuf_trim(dm->mb, 1); 2747b901d928SKonstantin Ananyev } 2748b901d928SKonstantin Ananyev 2749b901d928SKonstantin Ananyev static int 2750b901d928SKonstantin Ananyev test_ld_mbuf2_check(uint64_t rc, const void *arg) 2751b901d928SKonstantin Ananyev { 2752b901d928SKonstantin Ananyev return cmp_res(__func__, 0, rc, arg, arg, 0); 2753b901d928SKonstantin Ananyev } 2754b901d928SKonstantin Ananyev 2755b901d928SKonstantin Ananyev /* same as test_ld_mbuf1, but now store intermediate results on the stack */ 2756b901d928SKonstantin Ananyev static const struct ebpf_insn test_ld_mbuf3_prog[] = { 2757b901d928SKonstantin Ananyev 2758b901d928SKonstantin Ananyev /* BPF_ABS/BPF_IND implicitly expect mbuf ptr in R6 */ 2759b901d928SKonstantin Ananyev { 2760b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2761b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_6, 2762b901d928SKonstantin Ananyev .src_reg = EBPF_REG_1, 2763b901d928SKonstantin Ananyev }, 2764b901d928SKonstantin Ananyev /* load IPv4 version and IHL */ 2765b901d928SKonstantin Ananyev { 2766b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_B), 2767b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, version_ihl), 2768b901d928SKonstantin Ananyev }, 2769b901d928SKonstantin Ananyev /* check IP version */ 2770b901d928SKonstantin Ananyev { 2771b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2772b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2773b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2774b901d928SKonstantin Ananyev }, 2775b901d928SKonstantin Ananyev { 2776b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 2777b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2778b901d928SKonstantin Ananyev .imm = 0xf0, 2779b901d928SKonstantin Ananyev }, 2780b901d928SKonstantin Ananyev { 2781b901d928SKonstantin Ananyev .code = (BPF_JMP | BPF_JEQ | BPF_K), 2782b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_2, 2783b901d928SKonstantin Ananyev .imm = IPVERSION << 4, 2784b901d928SKonstantin Ananyev .off = 2, 2785b901d928SKonstantin Ananyev }, 2786b901d928SKonstantin Ananyev /* invalid IP version, return 0 */ 2787b901d928SKonstantin Ananyev { 2788b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_XOR | BPF_X), 2789b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2790b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2791b901d928SKonstantin Ananyev }, 2792b901d928SKonstantin Ananyev { 2793b901d928SKonstantin Ananyev .code = (BPF_JMP | EBPF_EXIT), 2794b901d928SKonstantin Ananyev }, 2795b901d928SKonstantin Ananyev /* load 3-rd byte of IP data */ 2796b901d928SKonstantin Ananyev { 2797b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_AND | BPF_K), 2798b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2799b901d928SKonstantin Ananyev .imm = RTE_IPV4_HDR_IHL_MASK, 2800b901d928SKonstantin Ananyev }, 2801b901d928SKonstantin Ananyev { 2802b901d928SKonstantin Ananyev .code = (BPF_ALU | BPF_LSH | BPF_K), 2803b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2804b901d928SKonstantin Ananyev .imm = 2, 2805b901d928SKonstantin Ananyev }, 2806b901d928SKonstantin Ananyev { 2807b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_B), 2808b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2809b901d928SKonstantin Ananyev .imm = 3, 2810b901d928SKonstantin Ananyev }, 2811b901d928SKonstantin Ananyev { 2812b901d928SKonstantin Ananyev .code = (BPF_STX | BPF_MEM | BPF_B), 2813b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_10, 2814b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2815b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u8) - 2816b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2817b901d928SKonstantin Ananyev }, 2818b901d928SKonstantin Ananyev /* load IPv4 src addr */ 2819b901d928SKonstantin Ananyev { 2820b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_W), 2821b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, src_addr), 2822b901d928SKonstantin Ananyev }, 2823b901d928SKonstantin Ananyev { 2824b901d928SKonstantin Ananyev .code = (BPF_STX | BPF_MEM | BPF_W), 2825b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_10, 2826b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2827b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u32) - 2828b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2829b901d928SKonstantin Ananyev }, 2830b901d928SKonstantin Ananyev /* load IPv4 total length */ 2831b901d928SKonstantin Ananyev { 2832b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_ABS | BPF_H), 2833b901d928SKonstantin Ananyev .imm = offsetof(struct rte_ipv4_hdr, total_length), 2834b901d928SKonstantin Ananyev }, 2835b901d928SKonstantin Ananyev { 2836b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | EBPF_MOV | BPF_X), 2837b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_8, 2838b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2839b901d928SKonstantin Ananyev }, 2840b901d928SKonstantin Ananyev /* load last 4 bytes of IP data */ 2841b901d928SKonstantin Ananyev { 2842b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_W), 2843b901d928SKonstantin Ananyev .src_reg = EBPF_REG_8, 2844b901d928SKonstantin Ananyev .imm = -(int32_t)sizeof(uint32_t), 2845b901d928SKonstantin Ananyev }, 2846b901d928SKonstantin Ananyev { 2847b901d928SKonstantin Ananyev .code = (BPF_STX | BPF_MEM | EBPF_DW), 2848b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_10, 2849b901d928SKonstantin Ananyev .src_reg = EBPF_REG_0, 2850b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u64) - 2851b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2852b901d928SKonstantin Ananyev }, 2853b901d928SKonstantin Ananyev /* load 2 bytes from the middle of IP data */ 2854b901d928SKonstantin Ananyev { 2855b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_RSH | BPF_K), 2856b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_8, 2857b901d928SKonstantin Ananyev .imm = 1, 2858b901d928SKonstantin Ananyev }, 2859b901d928SKonstantin Ananyev { 2860b901d928SKonstantin Ananyev .code = (BPF_LD | BPF_IND | BPF_H), 2861b901d928SKonstantin Ananyev .src_reg = EBPF_REG_8, 2862b901d928SKonstantin Ananyev }, 2863b901d928SKonstantin Ananyev { 2864b901d928SKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | EBPF_DW), 2865b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_1, 2866b901d928SKonstantin Ananyev .src_reg = EBPF_REG_10, 2867b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u64) - 2868b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2869b901d928SKonstantin Ananyev }, 2870b901d928SKonstantin Ananyev { 2871b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2872b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2873b901d928SKonstantin Ananyev .src_reg = EBPF_REG_1, 2874b901d928SKonstantin Ananyev }, 2875b901d928SKonstantin Ananyev { 2876b901d928SKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | BPF_W), 2877b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_1, 2878b901d928SKonstantin Ananyev .src_reg = EBPF_REG_10, 2879b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u32) - 2880b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2881b901d928SKonstantin Ananyev }, 2882b901d928SKonstantin Ananyev { 2883b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2884b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2885b901d928SKonstantin Ananyev .src_reg = EBPF_REG_1, 2886b901d928SKonstantin Ananyev }, 2887b901d928SKonstantin Ananyev { 2888b901d928SKonstantin Ananyev .code = (BPF_LDX | BPF_MEM | BPF_B), 2889b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_1, 2890b901d928SKonstantin Ananyev .src_reg = EBPF_REG_10, 2891b901d928SKonstantin Ananyev .off = (int16_t)(offsetof(struct dummy_offset, u8) - 2892b901d928SKonstantin Ananyev sizeof(struct dummy_offset)), 2893b901d928SKonstantin Ananyev }, 2894b901d928SKonstantin Ananyev { 2895b901d928SKonstantin Ananyev .code = (EBPF_ALU64 | BPF_ADD | BPF_X), 2896b901d928SKonstantin Ananyev .dst_reg = EBPF_REG_0, 2897b901d928SKonstantin Ananyev .src_reg = EBPF_REG_1, 2898b901d928SKonstantin Ananyev }, 2899b901d928SKonstantin Ananyev { 2900b901d928SKonstantin Ananyev .code = (BPF_JMP | EBPF_EXIT), 2901b901d928SKonstantin Ananyev }, 2902b901d928SKonstantin Ananyev }; 2903b901d928SKonstantin Ananyev 290483633ba2SKonstantin Ananyev /* all bpf test cases */ 2905a9de470cSBruce Richardson static const struct bpf_test tests[] = { 2906a9de470cSBruce Richardson { 2907a9de470cSBruce Richardson .name = "test_store1", 2908a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 2909a9de470cSBruce Richardson .prm = { 2910a9de470cSBruce Richardson .ins = test_store1_prog, 2911a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_store1_prog), 2912a9de470cSBruce Richardson .prog_arg = { 2913a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2914a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 2915a9de470cSBruce Richardson }, 2916a9de470cSBruce Richardson }, 2917a9de470cSBruce Richardson .prepare = test_store1_prepare, 2918a9de470cSBruce Richardson .check_result = test_store1_check, 2919a9de470cSBruce Richardson }, 2920a9de470cSBruce Richardson { 2921a9de470cSBruce Richardson .name = "test_store2", 2922a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 2923a9de470cSBruce Richardson .prm = { 2924a9de470cSBruce Richardson .ins = test_store2_prog, 2925a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_store2_prog), 2926a9de470cSBruce Richardson .prog_arg = { 2927a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2928a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 2929a9de470cSBruce Richardson }, 2930a9de470cSBruce Richardson }, 2931a9de470cSBruce Richardson .prepare = test_store1_prepare, 2932a9de470cSBruce Richardson .check_result = test_store1_check, 2933a9de470cSBruce Richardson }, 2934a9de470cSBruce Richardson { 2935a9de470cSBruce Richardson .name = "test_load1", 2936a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 2937a9de470cSBruce Richardson .prm = { 2938a9de470cSBruce Richardson .ins = test_load1_prog, 2939a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_load1_prog), 2940a9de470cSBruce Richardson .prog_arg = { 2941a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2942a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 2943a9de470cSBruce Richardson }, 2944a9de470cSBruce Richardson }, 2945a9de470cSBruce Richardson .prepare = test_load1_prepare, 2946a9de470cSBruce Richardson .check_result = test_load1_check, 2947a9de470cSBruce Richardson }, 2948a9de470cSBruce Richardson { 2949a9de470cSBruce Richardson .name = "test_ldimm1", 2950a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 2951a9de470cSBruce Richardson .prm = { 2952a9de470cSBruce Richardson .ins = test_ldimm1_prog, 2953a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_ldimm1_prog), 2954a9de470cSBruce Richardson .prog_arg = { 2955a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2956a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 2957a9de470cSBruce Richardson }, 2958a9de470cSBruce Richardson }, 2959a9de470cSBruce Richardson .prepare = test_store1_prepare, 2960a9de470cSBruce Richardson .check_result = test_ldimm1_check, 2961a9de470cSBruce Richardson }, 2962a9de470cSBruce Richardson { 2963a9de470cSBruce Richardson .name = "test_mul1", 2964a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 2965a9de470cSBruce Richardson .prm = { 2966a9de470cSBruce Richardson .ins = test_mul1_prog, 2967a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_mul1_prog), 2968a9de470cSBruce Richardson .prog_arg = { 2969a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2970a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 2971a9de470cSBruce Richardson }, 2972a9de470cSBruce Richardson }, 2973a9de470cSBruce Richardson .prepare = test_mul1_prepare, 2974a9de470cSBruce Richardson .check_result = test_mul1_check, 2975a9de470cSBruce Richardson }, 2976a9de470cSBruce Richardson { 2977a9de470cSBruce Richardson .name = "test_shift1", 2978a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 2979a9de470cSBruce Richardson .prm = { 2980a9de470cSBruce Richardson .ins = test_shift1_prog, 2981a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_shift1_prog), 2982a9de470cSBruce Richardson .prog_arg = { 2983a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2984a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 2985a9de470cSBruce Richardson }, 2986a9de470cSBruce Richardson }, 2987a9de470cSBruce Richardson .prepare = test_shift1_prepare, 2988a9de470cSBruce Richardson .check_result = test_shift1_check, 2989a9de470cSBruce Richardson }, 2990a9de470cSBruce Richardson { 2991a9de470cSBruce Richardson .name = "test_jump1", 2992a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 2993a9de470cSBruce Richardson .prm = { 2994a9de470cSBruce Richardson .ins = test_jump1_prog, 2995a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_jump1_prog), 2996a9de470cSBruce Richardson .prog_arg = { 2997a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 2998a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 2999a9de470cSBruce Richardson }, 3000a9de470cSBruce Richardson }, 3001a9de470cSBruce Richardson .prepare = test_jump1_prepare, 3002a9de470cSBruce Richardson .check_result = test_jump1_check, 3003a9de470cSBruce Richardson }, 3004a9de470cSBruce Richardson { 3005cddd8795SHarman Kalra .name = "test_jump2", 3006cddd8795SHarman Kalra .arg_sz = sizeof(struct dummy_net), 3007cddd8795SHarman Kalra .prm = { 3008cddd8795SHarman Kalra .ins = test_jump2_prog, 3009cddd8795SHarman Kalra .nb_ins = RTE_DIM(test_jump2_prog), 3010cddd8795SHarman Kalra .prog_arg = { 3011cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 3012cddd8795SHarman Kalra .size = sizeof(struct dummy_net), 3013cddd8795SHarman Kalra }, 3014cddd8795SHarman Kalra }, 3015cddd8795SHarman Kalra .prepare = test_jump2_prepare, 3016cddd8795SHarman Kalra .check_result = test_jump2_check, 3017cddd8795SHarman Kalra }, 3018cddd8795SHarman Kalra { 3019a9de470cSBruce Richardson .name = "test_alu1", 3020a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 3021a9de470cSBruce Richardson .prm = { 3022a9de470cSBruce Richardson .ins = test_alu1_prog, 3023a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_alu1_prog), 3024a9de470cSBruce Richardson .prog_arg = { 3025a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3026a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 3027a9de470cSBruce Richardson }, 3028a9de470cSBruce Richardson }, 3029a9de470cSBruce Richardson .prepare = test_jump1_prepare, 3030a9de470cSBruce Richardson .check_result = test_alu1_check, 3031a9de470cSBruce Richardson }, 3032a9de470cSBruce Richardson { 3033a9de470cSBruce Richardson .name = "test_bele1", 3034a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 3035a9de470cSBruce Richardson .prm = { 3036a9de470cSBruce Richardson .ins = test_bele1_prog, 3037a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_bele1_prog), 3038a9de470cSBruce Richardson .prog_arg = { 3039a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3040a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 3041a9de470cSBruce Richardson }, 3042a9de470cSBruce Richardson }, 3043a9de470cSBruce Richardson .prepare = test_bele1_prepare, 3044a9de470cSBruce Richardson .check_result = test_bele1_check, 3045a9de470cSBruce Richardson }, 3046a9de470cSBruce Richardson { 3047a9de470cSBruce Richardson .name = "test_xadd1", 3048a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 3049a9de470cSBruce Richardson .prm = { 3050a9de470cSBruce Richardson .ins = test_xadd1_prog, 3051a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_xadd1_prog), 3052a9de470cSBruce Richardson .prog_arg = { 3053a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3054a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 3055a9de470cSBruce Richardson }, 3056a9de470cSBruce Richardson }, 3057a9de470cSBruce Richardson .prepare = test_store1_prepare, 3058a9de470cSBruce Richardson .check_result = test_xadd1_check, 3059a9de470cSBruce Richardson }, 3060a9de470cSBruce Richardson { 3061a9de470cSBruce Richardson .name = "test_div1", 3062a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_vect8), 3063a9de470cSBruce Richardson .prm = { 3064a9de470cSBruce Richardson .ins = test_div1_prog, 3065a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_div1_prog), 3066a9de470cSBruce Richardson .prog_arg = { 3067a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3068a9de470cSBruce Richardson .size = sizeof(struct dummy_vect8), 3069a9de470cSBruce Richardson }, 3070a9de470cSBruce Richardson }, 3071a9de470cSBruce Richardson .prepare = test_mul1_prepare, 3072a9de470cSBruce Richardson .check_result = test_div1_check, 3073a9de470cSBruce Richardson }, 3074a9de470cSBruce Richardson { 3075a9de470cSBruce Richardson .name = "test_call1", 3076a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 3077a9de470cSBruce Richardson .prm = { 3078a9de470cSBruce Richardson .ins = test_call1_prog, 3079a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_call1_prog), 3080a9de470cSBruce Richardson .prog_arg = { 3081a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3082a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 3083a9de470cSBruce Richardson }, 3084a9de470cSBruce Richardson .xsym = test_call1_xsym, 3085a9de470cSBruce Richardson .nb_xsym = RTE_DIM(test_call1_xsym), 3086a9de470cSBruce Richardson }, 3087a9de470cSBruce Richardson .prepare = test_load1_prepare, 3088a9de470cSBruce Richardson .check_result = test_call1_check, 3089a9de470cSBruce Richardson /* for now don't support function calls on 32 bit platform */ 3090a9de470cSBruce Richardson .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3091a9de470cSBruce Richardson }, 3092a9de470cSBruce Richardson { 3093a9de470cSBruce Richardson .name = "test_call2", 3094a9de470cSBruce Richardson .arg_sz = sizeof(struct dummy_offset), 3095a9de470cSBruce Richardson .prm = { 3096a9de470cSBruce Richardson .ins = test_call2_prog, 3097a9de470cSBruce Richardson .nb_ins = RTE_DIM(test_call2_prog), 3098a9de470cSBruce Richardson .prog_arg = { 3099a9de470cSBruce Richardson .type = RTE_BPF_ARG_PTR, 3100a9de470cSBruce Richardson .size = sizeof(struct dummy_offset), 3101a9de470cSBruce Richardson }, 3102a9de470cSBruce Richardson .xsym = test_call2_xsym, 3103a9de470cSBruce Richardson .nb_xsym = RTE_DIM(test_call2_xsym), 3104a9de470cSBruce Richardson }, 3105a9de470cSBruce Richardson .prepare = test_store1_prepare, 3106a9de470cSBruce Richardson .check_result = test_call2_check, 3107a9de470cSBruce Richardson /* for now don't support function calls on 32 bit platform */ 3108a9de470cSBruce Richardson .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3109a9de470cSBruce Richardson }, 31107e30313fSKonstantin Ananyev { 31117e30313fSKonstantin Ananyev .name = "test_call3", 31127e30313fSKonstantin Ananyev .arg_sz = sizeof(struct dummy_vect8), 31137e30313fSKonstantin Ananyev .prm = { 31147e30313fSKonstantin Ananyev .ins = test_call3_prog, 31157e30313fSKonstantin Ananyev .nb_ins = RTE_DIM(test_call3_prog), 31167e30313fSKonstantin Ananyev .prog_arg = { 31177e30313fSKonstantin Ananyev .type = RTE_BPF_ARG_PTR, 31187e30313fSKonstantin Ananyev .size = sizeof(struct dummy_vect8), 31197e30313fSKonstantin Ananyev }, 31207e30313fSKonstantin Ananyev .xsym = test_call3_xsym, 31217e30313fSKonstantin Ananyev .nb_xsym = RTE_DIM(test_call3_xsym), 31227e30313fSKonstantin Ananyev }, 31237e30313fSKonstantin Ananyev .prepare = test_call3_prepare, 31247e30313fSKonstantin Ananyev .check_result = test_call3_check, 31257e30313fSKonstantin Ananyev /* for now don't support function calls on 32 bit platform */ 31267e30313fSKonstantin Ananyev .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 31277e30313fSKonstantin Ananyev }, 3128cddd8795SHarman Kalra { 3129cddd8795SHarman Kalra .name = "test_call4", 3130cddd8795SHarman Kalra .arg_sz = sizeof(struct dummy_offset), 3131cddd8795SHarman Kalra .prm = { 3132cddd8795SHarman Kalra .ins = test_call4_prog, 3133cddd8795SHarman Kalra .nb_ins = RTE_DIM(test_call4_prog), 3134cddd8795SHarman Kalra .prog_arg = { 3135cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 3136cddd8795SHarman Kalra .size = 2 * sizeof(struct dummy_offset), 3137cddd8795SHarman Kalra }, 3138cddd8795SHarman Kalra .xsym = test_call4_xsym, 3139cddd8795SHarman Kalra .nb_xsym = RTE_DIM(test_call4_xsym), 3140cddd8795SHarman Kalra }, 3141cddd8795SHarman Kalra .prepare = test_store1_prepare, 3142cddd8795SHarman Kalra .check_result = test_call4_check, 3143cddd8795SHarman Kalra /* for now don't support function calls on 32 bit platform */ 3144cddd8795SHarman Kalra .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3145cddd8795SHarman Kalra }, 3146cddd8795SHarman Kalra { 3147cddd8795SHarman Kalra .name = "test_call5", 3148cddd8795SHarman Kalra .arg_sz = sizeof(struct dummy_offset), 3149cddd8795SHarman Kalra .prm = { 3150cddd8795SHarman Kalra .ins = test_call5_prog, 3151cddd8795SHarman Kalra .nb_ins = RTE_DIM(test_call5_prog), 3152cddd8795SHarman Kalra .prog_arg = { 3153cddd8795SHarman Kalra .type = RTE_BPF_ARG_PTR, 3154cddd8795SHarman Kalra .size = sizeof(struct dummy_offset), 3155cddd8795SHarman Kalra }, 3156cddd8795SHarman Kalra .xsym = test_call5_xsym, 3157cddd8795SHarman Kalra .nb_xsym = RTE_DIM(test_call5_xsym), 3158cddd8795SHarman Kalra }, 3159cddd8795SHarman Kalra .prepare = test_store1_prepare, 3160cddd8795SHarman Kalra .check_result = test_call5_check, 3161cddd8795SHarman Kalra /* for now don't support function calls on 32 bit platform */ 3162cddd8795SHarman Kalra .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3163cddd8795SHarman Kalra }, 3164b901d928SKonstantin Ananyev { 3165b901d928SKonstantin Ananyev .name = "test_ld_mbuf1", 3166b901d928SKonstantin Ananyev .arg_sz = sizeof(struct dummy_mbuf), 3167b901d928SKonstantin Ananyev .prm = { 3168b901d928SKonstantin Ananyev .ins = test_ld_mbuf1_prog, 3169b901d928SKonstantin Ananyev .nb_ins = RTE_DIM(test_ld_mbuf1_prog), 3170b901d928SKonstantin Ananyev .prog_arg = { 3171b901d928SKonstantin Ananyev .type = RTE_BPF_ARG_PTR_MBUF, 3172b901d928SKonstantin Ananyev .buf_size = sizeof(struct dummy_mbuf), 3173b901d928SKonstantin Ananyev }, 3174b901d928SKonstantin Ananyev }, 3175b901d928SKonstantin Ananyev .prepare = test_ld_mbuf1_prepare, 3176b901d928SKonstantin Ananyev .check_result = test_ld_mbuf1_check, 3177b901d928SKonstantin Ananyev /* mbuf as input argument is not supported on 32 bit platform */ 3178b901d928SKonstantin Ananyev .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3179b901d928SKonstantin Ananyev }, 3180b901d928SKonstantin Ananyev { 3181b901d928SKonstantin Ananyev .name = "test_ld_mbuf2", 3182b901d928SKonstantin Ananyev .arg_sz = sizeof(struct dummy_mbuf), 3183b901d928SKonstantin Ananyev .prm = { 3184b901d928SKonstantin Ananyev .ins = test_ld_mbuf1_prog, 3185b901d928SKonstantin Ananyev .nb_ins = RTE_DIM(test_ld_mbuf1_prog), 3186b901d928SKonstantin Ananyev .prog_arg = { 3187b901d928SKonstantin Ananyev .type = RTE_BPF_ARG_PTR_MBUF, 3188b901d928SKonstantin Ananyev .buf_size = sizeof(struct dummy_mbuf), 3189b901d928SKonstantin Ananyev }, 3190b901d928SKonstantin Ananyev }, 3191b901d928SKonstantin Ananyev .prepare = test_ld_mbuf2_prepare, 3192b901d928SKonstantin Ananyev .check_result = test_ld_mbuf2_check, 3193b901d928SKonstantin Ananyev /* mbuf as input argument is not supported on 32 bit platform */ 3194b901d928SKonstantin Ananyev .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3195b901d928SKonstantin Ananyev }, 3196b901d928SKonstantin Ananyev { 3197b901d928SKonstantin Ananyev .name = "test_ld_mbuf3", 3198b901d928SKonstantin Ananyev .arg_sz = sizeof(struct dummy_mbuf), 3199b901d928SKonstantin Ananyev .prm = { 3200b901d928SKonstantin Ananyev .ins = test_ld_mbuf3_prog, 3201b901d928SKonstantin Ananyev .nb_ins = RTE_DIM(test_ld_mbuf3_prog), 3202b901d928SKonstantin Ananyev .prog_arg = { 3203b901d928SKonstantin Ananyev .type = RTE_BPF_ARG_PTR_MBUF, 3204b901d928SKonstantin Ananyev .buf_size = sizeof(struct dummy_mbuf), 3205b901d928SKonstantin Ananyev }, 3206b901d928SKonstantin Ananyev }, 3207b901d928SKonstantin Ananyev .prepare = test_ld_mbuf1_prepare, 3208b901d928SKonstantin Ananyev .check_result = test_ld_mbuf1_check, 3209b901d928SKonstantin Ananyev /* mbuf as input argument is not supported on 32 bit platform */ 3210b901d928SKonstantin Ananyev .allow_fail = (sizeof(uint64_t) != sizeof(uintptr_t)), 3211b901d928SKonstantin Ananyev }, 3212a9de470cSBruce Richardson }; 3213a9de470cSBruce Richardson 3214a9de470cSBruce Richardson static int 3215a9de470cSBruce Richardson run_test(const struct bpf_test *tst) 3216a9de470cSBruce Richardson { 3217a9de470cSBruce Richardson int32_t ret, rv; 3218a9de470cSBruce Richardson int64_t rc; 3219a9de470cSBruce Richardson struct rte_bpf *bpf; 3220a9de470cSBruce Richardson struct rte_bpf_jit jit; 3221a9de470cSBruce Richardson uint8_t tbuf[tst->arg_sz]; 3222a9de470cSBruce Richardson 3223a9de470cSBruce Richardson printf("%s(%s) start\n", __func__, tst->name); 3224a9de470cSBruce Richardson 3225a9de470cSBruce Richardson bpf = rte_bpf_load(&tst->prm); 3226a9de470cSBruce Richardson if (bpf == NULL) { 3227a9de470cSBruce Richardson printf("%s@%d: failed to load bpf code, error=%d(%s);\n", 3228a9de470cSBruce Richardson __func__, __LINE__, rte_errno, strerror(rte_errno)); 3229a9de470cSBruce Richardson return -1; 3230a9de470cSBruce Richardson } 3231a9de470cSBruce Richardson 3232a9de470cSBruce Richardson tst->prepare(tbuf); 3233a9de470cSBruce Richardson rc = rte_bpf_exec(bpf, tbuf); 3234a9de470cSBruce Richardson ret = tst->check_result(rc, tbuf); 3235a9de470cSBruce Richardson if (ret != 0) { 3236a9de470cSBruce Richardson printf("%s@%d: check_result(%s) failed, error: %d(%s);\n", 3237a9de470cSBruce Richardson __func__, __LINE__, tst->name, ret, strerror(ret)); 3238a9de470cSBruce Richardson } 3239a9de470cSBruce Richardson 324083633ba2SKonstantin Ananyev /* repeat the same test with jit, when possible */ 3241a9de470cSBruce Richardson rte_bpf_get_jit(bpf, &jit); 324283633ba2SKonstantin Ananyev if (jit.func != NULL) { 3243a9de470cSBruce Richardson 3244a9de470cSBruce Richardson tst->prepare(tbuf); 3245a9de470cSBruce Richardson rc = jit.func(tbuf); 3246a9de470cSBruce Richardson rv = tst->check_result(rc, tbuf); 3247a9de470cSBruce Richardson ret |= rv; 3248a9de470cSBruce Richardson if (rv != 0) { 324983633ba2SKonstantin Ananyev printf("%s@%d: check_result(%s) failed, " 325083633ba2SKonstantin Ananyev "error: %d(%s);\n", 325183633ba2SKonstantin Ananyev __func__, __LINE__, tst->name, 32527eff355bSMin Hu (Connor) rv, strerror(rv)); 325383633ba2SKonstantin Ananyev } 3254a9de470cSBruce Richardson } 3255a9de470cSBruce Richardson 3256a9de470cSBruce Richardson rte_bpf_destroy(bpf); 3257a9de470cSBruce Richardson return ret; 3258a9de470cSBruce Richardson 3259a9de470cSBruce Richardson } 3260a9de470cSBruce Richardson 3261a9de470cSBruce Richardson static int 3262a9de470cSBruce Richardson test_bpf(void) 3263a9de470cSBruce Richardson { 3264a9de470cSBruce Richardson int32_t rc, rv; 3265a9de470cSBruce Richardson uint32_t i; 3266a9de470cSBruce Richardson 3267a9de470cSBruce Richardson rc = 0; 3268a9de470cSBruce Richardson for (i = 0; i != RTE_DIM(tests); i++) { 3269a9de470cSBruce Richardson rv = run_test(tests + i); 3270a9de470cSBruce Richardson if (tests[i].allow_fail == 0) 3271a9de470cSBruce Richardson rc |= rv; 3272a9de470cSBruce Richardson } 3273a9de470cSBruce Richardson 3274a9de470cSBruce Richardson return rc; 3275a9de470cSBruce Richardson } 3276a9de470cSBruce Richardson 32773c60274cSJie Zhou #endif /* !RTE_LIB_BPF */ 32783c60274cSJie Zhou 3279e0a8442cSBruce Richardson REGISTER_FAST_TEST(bpf_autotest, true, true, test_bpf); 32802eccf6afSStephen Hemminger 328155ae8965STyler Retzlaff #ifndef RTE_HAS_LIBPCAP 328255ae8965STyler Retzlaff 328355ae8965STyler Retzlaff static int 328455ae8965STyler Retzlaff test_bpf_convert(void) 328555ae8965STyler Retzlaff { 328655ae8965STyler Retzlaff printf("BPF convert RTE_HAS_LIBPCAP is undefined, skipping test\n"); 328755ae8965STyler Retzlaff return TEST_SKIPPED; 328855ae8965STyler Retzlaff } 328955ae8965STyler Retzlaff 329055ae8965STyler Retzlaff #else 32912eccf6afSStephen Hemminger #include <pcap/pcap.h> 32922eccf6afSStephen Hemminger 32932eccf6afSStephen Hemminger static void 32942eccf6afSStephen Hemminger test_bpf_dump(struct bpf_program *cbf, const struct rte_bpf_prm *prm) 32952eccf6afSStephen Hemminger { 32962eccf6afSStephen Hemminger printf("cBPF program (%u insns)\n", cbf->bf_len); 32972eccf6afSStephen Hemminger bpf_dump(cbf, 1); 32982eccf6afSStephen Hemminger 329978e7b29fSStephen Hemminger if (prm != NULL) { 33002eccf6afSStephen Hemminger printf("\neBPF program (%u insns)\n", prm->nb_ins); 33012eccf6afSStephen Hemminger rte_bpf_dump(stdout, prm->ins, prm->nb_ins); 33022eccf6afSStephen Hemminger } 330378e7b29fSStephen Hemminger } 33042eccf6afSStephen Hemminger 33052eccf6afSStephen Hemminger static int 33062eccf6afSStephen Hemminger test_bpf_match(pcap_t *pcap, const char *str, 33072eccf6afSStephen Hemminger struct rte_mbuf *mb) 33082eccf6afSStephen Hemminger { 33092eccf6afSStephen Hemminger struct bpf_program fcode; 33102eccf6afSStephen Hemminger struct rte_bpf_prm *prm = NULL; 33112eccf6afSStephen Hemminger struct rte_bpf *bpf = NULL; 33122eccf6afSStephen Hemminger int ret = -1; 33132eccf6afSStephen Hemminger uint64_t rc; 33142eccf6afSStephen Hemminger 33152eccf6afSStephen Hemminger if (pcap_compile(pcap, &fcode, str, 1, PCAP_NETMASK_UNKNOWN)) { 33162eccf6afSStephen Hemminger printf("%s@%d: pcap_compile(\"%s\") failed: %s;\n", 33172eccf6afSStephen Hemminger __func__, __LINE__, str, pcap_geterr(pcap)); 33182eccf6afSStephen Hemminger return -1; 33192eccf6afSStephen Hemminger } 33202eccf6afSStephen Hemminger 33212eccf6afSStephen Hemminger prm = rte_bpf_convert(&fcode); 33222eccf6afSStephen Hemminger if (prm == NULL) { 33232eccf6afSStephen Hemminger printf("%s@%d: bpf_convert('%s') failed,, error=%d(%s);\n", 33242eccf6afSStephen Hemminger __func__, __LINE__, str, rte_errno, strerror(rte_errno)); 33252eccf6afSStephen Hemminger goto error; 33262eccf6afSStephen Hemminger } 33272eccf6afSStephen Hemminger 33282eccf6afSStephen Hemminger bpf = rte_bpf_load(prm); 33292eccf6afSStephen Hemminger if (bpf == NULL) { 33302eccf6afSStephen Hemminger printf("%s@%d: failed to load bpf code, error=%d(%s);\n", 33312eccf6afSStephen Hemminger __func__, __LINE__, rte_errno, strerror(rte_errno)); 33322eccf6afSStephen Hemminger goto error; 33332eccf6afSStephen Hemminger } 33342eccf6afSStephen Hemminger 33352eccf6afSStephen Hemminger rc = rte_bpf_exec(bpf, mb); 33362eccf6afSStephen Hemminger /* The return code from bpf capture filter is non-zero if matched */ 33372eccf6afSStephen Hemminger ret = (rc == 0); 33382eccf6afSStephen Hemminger error: 33392eccf6afSStephen Hemminger if (bpf) 33402eccf6afSStephen Hemminger rte_bpf_destroy(bpf); 33412eccf6afSStephen Hemminger rte_free(prm); 33422eccf6afSStephen Hemminger pcap_freecode(&fcode); 33432eccf6afSStephen Hemminger return ret; 33442eccf6afSStephen Hemminger } 33452eccf6afSStephen Hemminger 33462eccf6afSStephen Hemminger /* Basic sanity test can we match a IP packet */ 33472eccf6afSStephen Hemminger static int 33482eccf6afSStephen Hemminger test_bpf_filter_sanity(pcap_t *pcap) 33492eccf6afSStephen Hemminger { 33502eccf6afSStephen Hemminger const uint32_t plen = 100; 33512eccf6afSStephen Hemminger struct rte_mbuf mb, *m; 33522eccf6afSStephen Hemminger uint8_t tbuf[RTE_MBUF_DEFAULT_BUF_SIZE]; 33532eccf6afSStephen Hemminger struct { 33542eccf6afSStephen Hemminger struct rte_ether_hdr eth_hdr; 33552eccf6afSStephen Hemminger struct rte_ipv4_hdr ip_hdr; 33562eccf6afSStephen Hemminger } *hdr; 33572eccf6afSStephen Hemminger 33587d0420acSStephen Hemminger memset(&mb, 0, sizeof(mb)); 33592eccf6afSStephen Hemminger dummy_mbuf_prep(&mb, tbuf, sizeof(tbuf), plen); 33602eccf6afSStephen Hemminger m = &mb; 33612eccf6afSStephen Hemminger 33622eccf6afSStephen Hemminger hdr = rte_pktmbuf_mtod(m, typeof(hdr)); 33632eccf6afSStephen Hemminger hdr->eth_hdr = (struct rte_ether_hdr) { 3364*e0d947a1SFerruh Yigit .dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 33652eccf6afSStephen Hemminger .ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4), 33662eccf6afSStephen Hemminger }; 33672eccf6afSStephen Hemminger hdr->ip_hdr = (struct rte_ipv4_hdr) { 33682eccf6afSStephen Hemminger .version_ihl = RTE_IPV4_VHL_DEF, 33692eccf6afSStephen Hemminger .total_length = rte_cpu_to_be_16(plen), 33702eccf6afSStephen Hemminger .time_to_live = IPDEFTTL, 33712eccf6afSStephen Hemminger .next_proto_id = IPPROTO_RAW, 33722eccf6afSStephen Hemminger .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK), 33732eccf6afSStephen Hemminger .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST), 33742eccf6afSStephen Hemminger }; 33752eccf6afSStephen Hemminger 33762eccf6afSStephen Hemminger if (test_bpf_match(pcap, "ip", m) != 0) { 33772eccf6afSStephen Hemminger printf("%s@%d: filter \"ip\" doesn't match test data\n", 33782eccf6afSStephen Hemminger __func__, __LINE__); 33792eccf6afSStephen Hemminger return -1; 33802eccf6afSStephen Hemminger } 33812eccf6afSStephen Hemminger if (test_bpf_match(pcap, "not ip", m) == 0) { 33822eccf6afSStephen Hemminger printf("%s@%d: filter \"not ip\" does match test data\n", 33832eccf6afSStephen Hemminger __func__, __LINE__); 33842eccf6afSStephen Hemminger return -1; 33852eccf6afSStephen Hemminger } 33862eccf6afSStephen Hemminger 33872eccf6afSStephen Hemminger return 0; 33882eccf6afSStephen Hemminger } 33892eccf6afSStephen Hemminger 33902eccf6afSStephen Hemminger /* 33912eccf6afSStephen Hemminger * Some sample pcap filter strings from 33922eccf6afSStephen Hemminger * https://wiki.wireshark.org/CaptureFilters 33932eccf6afSStephen Hemminger */ 33942eccf6afSStephen Hemminger static const char * const sample_filters[] = { 33952eccf6afSStephen Hemminger "host 172.18.5.4", 33962eccf6afSStephen Hemminger "net 192.168.0.0/24", 33972eccf6afSStephen Hemminger "src net 192.168.0.0/24", 33982eccf6afSStephen Hemminger "src net 192.168.0.0 mask 255.255.255.0", 33992eccf6afSStephen Hemminger "dst net 192.168.0.0/24", 34002eccf6afSStephen Hemminger "dst net 192.168.0.0 mask 255.255.255.0", 34012eccf6afSStephen Hemminger "port 53", 340279b3275aSStephen Hemminger "host 192.0.2.1 and not (port 80 or port 25)", 340379b3275aSStephen Hemminger "host 2001:4b98:db0::8 and not port 80 and not port 25", 34042eccf6afSStephen Hemminger "port not 53 and not arp", 34052eccf6afSStephen Hemminger "(tcp[0:2] > 1500 and tcp[0:2] < 1550) or (tcp[2:2] > 1500 and tcp[2:2] < 1550)", 34062eccf6afSStephen Hemminger "ether proto 0x888e", 34072eccf6afSStephen Hemminger "ether[0] & 1 = 0 and ip[16] >= 224", 34082eccf6afSStephen Hemminger "icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply", 34092eccf6afSStephen Hemminger "tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 and not src and dst net 127.0.0.1", 34102eccf6afSStephen Hemminger "not ether dst 01:80:c2:00:00:0e", 34112eccf6afSStephen Hemminger "not broadcast and not multicast", 34122eccf6afSStephen Hemminger "dst host ff02::1", 34132eccf6afSStephen Hemminger "port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420", 34142eccf6afSStephen Hemminger /* Worms */ 34152eccf6afSStephen Hemminger "dst port 135 and tcp port 135 and ip[2:2]==48", 34162eccf6afSStephen Hemminger "icmp[icmptype]==icmp-echo and ip[2:2]==92 and icmp[8:4]==0xAAAAAAAA", 34172eccf6afSStephen Hemminger "dst port 135 or dst port 445 or dst port 1433" 34182eccf6afSStephen Hemminger " and tcp[tcpflags] & (tcp-syn) != 0" 34192eccf6afSStephen Hemminger " and tcp[tcpflags] & (tcp-ack) = 0 and src net 192.168.0.0/24", 34202eccf6afSStephen Hemminger "tcp src port 443 and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4] = 0x18)" 34212eccf6afSStephen Hemminger " and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4 + 1] = 0x03)" 34222eccf6afSStephen Hemminger " and (tcp[((tcp[12] & 0xF0) >> 4 ) * 4 + 2] < 0x04)" 34232eccf6afSStephen Hemminger " and ((ip[2:2] - 4 * (ip[0] & 0x0F) - 4 * ((tcp[12] & 0xF0) >> 4) > 69))", 34242eccf6afSStephen Hemminger /* Other */ 34252eccf6afSStephen Hemminger "len = 128", 3426a5d4e246SKonstantin Ananyev "host 1::1 or host 1::1 or host 1::1 or host 1::1 or host 1::1 or host 1::1", 3427a5d4e246SKonstantin Ananyev ("host 1::1 or host 1::2 or host 1::3 or host 1::4 or host 1::5 " 3428a5d4e246SKonstantin Ananyev "or host 192.0.2.1 or host 192.0.2.100 or host 192.0.2.200"), 34292eccf6afSStephen Hemminger }; 34302eccf6afSStephen Hemminger 34312eccf6afSStephen Hemminger static int 34322eccf6afSStephen Hemminger test_bpf_filter(pcap_t *pcap, const char *s) 34332eccf6afSStephen Hemminger { 34342eccf6afSStephen Hemminger struct bpf_program fcode; 34352eccf6afSStephen Hemminger struct rte_bpf_prm *prm = NULL; 34362eccf6afSStephen Hemminger struct rte_bpf *bpf = NULL; 34372eccf6afSStephen Hemminger 34382eccf6afSStephen Hemminger if (pcap_compile(pcap, &fcode, s, 1, PCAP_NETMASK_UNKNOWN)) { 34392eccf6afSStephen Hemminger printf("%s@%d: pcap_compile('%s') failed: %s;\n", 34402eccf6afSStephen Hemminger __func__, __LINE__, s, pcap_geterr(pcap)); 34412eccf6afSStephen Hemminger return -1; 34422eccf6afSStephen Hemminger } 34432eccf6afSStephen Hemminger 34442eccf6afSStephen Hemminger prm = rte_bpf_convert(&fcode); 34452eccf6afSStephen Hemminger if (prm == NULL) { 34462eccf6afSStephen Hemminger printf("%s@%d: bpf_convert('%s') failed,, error=%d(%s);\n", 34472eccf6afSStephen Hemminger __func__, __LINE__, s, rte_errno, strerror(rte_errno)); 34482eccf6afSStephen Hemminger goto error; 34492eccf6afSStephen Hemminger } 34502eccf6afSStephen Hemminger 3451a5d4e246SKonstantin Ananyev printf("bpf convert for \"%s\" produced:\n", s); 3452a5d4e246SKonstantin Ananyev rte_bpf_dump(stdout, prm->ins, prm->nb_ins); 3453a5d4e246SKonstantin Ananyev 34542eccf6afSStephen Hemminger bpf = rte_bpf_load(prm); 34552eccf6afSStephen Hemminger if (bpf == NULL) { 34562eccf6afSStephen Hemminger printf("%s@%d: failed to load bpf code, error=%d(%s);\n", 34572eccf6afSStephen Hemminger __func__, __LINE__, rte_errno, strerror(rte_errno)); 34582eccf6afSStephen Hemminger goto error; 34592eccf6afSStephen Hemminger } 34602eccf6afSStephen Hemminger 34612eccf6afSStephen Hemminger error: 34622eccf6afSStephen Hemminger if (bpf) 34632eccf6afSStephen Hemminger rte_bpf_destroy(bpf); 34642eccf6afSStephen Hemminger else { 34652eccf6afSStephen Hemminger printf("%s \"%s\"\n", __func__, s); 34662eccf6afSStephen Hemminger test_bpf_dump(&fcode, prm); 34672eccf6afSStephen Hemminger } 34682eccf6afSStephen Hemminger 34692eccf6afSStephen Hemminger rte_free(prm); 34702eccf6afSStephen Hemminger pcap_freecode(&fcode); 34712eccf6afSStephen Hemminger return (bpf == NULL) ? -1 : 0; 34722eccf6afSStephen Hemminger } 34732eccf6afSStephen Hemminger 34742eccf6afSStephen Hemminger static int 34752eccf6afSStephen Hemminger test_bpf_convert(void) 34762eccf6afSStephen Hemminger { 34772eccf6afSStephen Hemminger unsigned int i; 34782eccf6afSStephen Hemminger pcap_t *pcap; 34792eccf6afSStephen Hemminger int rc; 34802eccf6afSStephen Hemminger 34812eccf6afSStephen Hemminger pcap = pcap_open_dead(DLT_EN10MB, 262144); 34822eccf6afSStephen Hemminger if (!pcap) { 34832eccf6afSStephen Hemminger printf("pcap_open_dead failed\n"); 34842eccf6afSStephen Hemminger return -1; 34852eccf6afSStephen Hemminger } 34862eccf6afSStephen Hemminger 34872eccf6afSStephen Hemminger rc = test_bpf_filter_sanity(pcap); 34882eccf6afSStephen Hemminger for (i = 0; i < RTE_DIM(sample_filters); i++) 34892eccf6afSStephen Hemminger rc |= test_bpf_filter(pcap, sample_filters[i]); 34902eccf6afSStephen Hemminger 34912eccf6afSStephen Hemminger pcap_close(pcap); 34922eccf6afSStephen Hemminger return rc; 34932eccf6afSStephen Hemminger } 34942eccf6afSStephen Hemminger 3495d6024c0aSDavid Marchand #endif /* RTE_HAS_LIBPCAP */ 349655ae8965STyler Retzlaff 3497e0a8442cSBruce Richardson REGISTER_FAST_TEST(bpf_convert_autotest, true, true, test_bpf_convert); 3498