xref: /dpdk/app/test/test_bpf.c (revision e0d947a1e6c2f80aa039a4f7082a8aa16797d8b9)
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