1314817Sngie/*	$NetBSD: t_bpfilter.c,v 1.11 2017/01/13 21:30:42 christos Exp $	*/
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2012 The NetBSD Foundation, Inc.
5272343Sngie *
6272343Sngie * Redistribution and use in source and binary forms, with or without
7272343Sngie * modification, are permitted provided that the following conditions
8272343Sngie * are met:
9272343Sngie * 1. Redistributions of source code must retain the above copyright
10272343Sngie *    notice, this list of conditions and the following disclaimer.
11272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
12272343Sngie *    notice, this list of conditions and the following disclaimer in the
13272343Sngie *    documentation and/or other materials provided with the distribution.
14272343Sngie *
15272343Sngie * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16272343Sngie * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17272343Sngie * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18272343Sngie * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19272343Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20272343Sngie * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21272343Sngie * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22272343Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23272343Sngie * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24272343Sngie * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25272343Sngie * SUCH DAMAGE.
26272343Sngie */
27272343Sngie#include <sys/cdefs.h>
28314817Sngie__RCSID("$NetBSD: t_bpfilter.c,v 1.11 2017/01/13 21:30:42 christos Exp $");
29272343Sngie
30272343Sngie#include <sys/param.h>
31272343Sngie#include <sys/ioctl.h>
32272343Sngie#include <sys/socket.h>
33272343Sngie#include <sys/mbuf.h>
34272343Sngie#include <sys/sysctl.h>
35272343Sngie#include <sys/mman.h>
36272343Sngie#include <sys/wait.h>
37272343Sngie#include <unistd.h>
38272343Sngie
39272343Sngie#include <net/if.h>
40272343Sngie#include <net/if_ether.h>
41272343Sngie#include <net/bpf.h>
42272343Sngie
43272343Sngie#include <fcntl.h>
44272343Sngie#include <stdint.h>
45272343Sngie#include <stdio.h>
46272343Sngie#include <string.h>
47272343Sngie
48272343Sngie#include <rump/rump.h>
49272343Sngie#include <rump/rump_syscalls.h>
50272343Sngie
51272343Sngie/* XXX: atf-c.h has collisions with mbuf */
52272343Sngie#undef m_type
53272343Sngie#undef m_data
54272343Sngie#include <atf-c.h>
55272343Sngie
56314817Sngie#include "h_macros.h"
57272343Sngie#include "../config/netconfig.c"
58272343Sngie
59272343Sngie
60272343Sngie#define SNAPLEN UINT32_MAX
61272343Sngie
62272343Sngie#define BMAGIC UINT32_C(0x37)
63272343Sngie#define HMAGIC UINT32_C(0xc2c2)
64272343Sngie#define WMAGIC UINT32_C(0x7d7d7d7d)
65272343Sngie
66272343Sngiestatic const char magic_echo_reply_tail[7] = {
67272343Sngie	BMAGIC,
68272343Sngie	HMAGIC & 0xff,
69272343Sngie	HMAGIC & 0xff,
70272343Sngie	WMAGIC & 0xff,
71272343Sngie	WMAGIC & 0xff,
72272343Sngie	WMAGIC & 0xff,
73272343Sngie	WMAGIC & 0xff
74272343Sngie};
75272343Sngie
76272343Sngie/*
77272343Sngie * Match ICMP_ECHOREPLY packet with 7 magic bytes at the end.
78272343Sngie */
79272343Sngiestatic struct bpf_insn magic_echo_reply_prog[] = {
80272343Sngie	BPF_STMT(BPF_LD+BPF_ABS+BPF_B,
81272343Sngie	    sizeof(struct ip) + offsetof(struct icmp, icmp_type)),
82272343Sngie	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ICMP_ECHOREPLY, 1, 0),
83272343Sngie	BPF_STMT(BPF_RET+BPF_K, 0),
84272343Sngie
85272343Sngie	BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),  /* A <- len   */
86272343Sngie	BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 7), /* A <- A - 7 */
87272343Sngie	BPF_STMT(BPF_MISC+BPF_TAX, 0),      /* X <- A     */
88272343Sngie
89272343Sngie	BPF_STMT(BPF_LD+BPF_IND+BPF_B, 0),
90272343Sngie	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, BMAGIC, 1, 0),
91272343Sngie	BPF_STMT(BPF_RET+BPF_K, 0),
92272343Sngie
93272343Sngie	BPF_STMT(BPF_LD+BPF_IND+BPF_H, 1),
94272343Sngie	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, HMAGIC, 1, 0),
95272343Sngie	BPF_STMT(BPF_RET+BPF_K, 0),
96272343Sngie
97272343Sngie	BPF_STMT(BPF_LD+BPF_IND+BPF_W, 3),
98272343Sngie	BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, WMAGIC, 1, 0),
99272343Sngie	BPF_STMT(BPF_RET+BPF_K, 0),
100272343Sngie
101272343Sngie	BPF_STMT(BPF_RET+BPF_K, SNAPLEN)
102272343Sngie};
103272343Sngie
104272343Sngiestatic struct bpf_insn badmem_prog[] = {
105272343Sngie	BPF_STMT(BPF_LD+BPF_MEM, 5),
106272343Sngie	BPF_STMT(BPF_RET+BPF_A, 0),
107272343Sngie};
108272343Sngie
109272343Sngiestatic struct bpf_insn noinitA_prog[] = {
110272343Sngie	BPF_STMT(BPF_RET+BPF_A, 0),
111272343Sngie};
112272343Sngie
113272343Sngiestatic struct bpf_insn noinitX_prog[] = {
114272343Sngie	BPF_STMT(BPF_MISC+BPF_TXA, 0),
115272343Sngie	BPF_STMT(BPF_RET+BPF_A, 0),
116272343Sngie};
117272343Sngie
118313498Sngiestatic struct bpf_insn badjmp_prog[] = {
119313498Sngie	BPF_STMT(BPF_JMP+BPF_JA, 5),
120313498Sngie	BPF_STMT(BPF_RET+BPF_A, 0),
121313498Sngie};
122313498Sngie
123313498Sngiestatic struct bpf_insn negjmp_prog[] = {
124313498Sngie	BPF_STMT(BPF_JMP+BPF_JA, 0),
125313498Sngie	BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2
126313498Sngie	BPF_STMT(BPF_RET+BPF_A, 0),
127313498Sngie};
128313498Sngie
129313498Sngiestatic struct bpf_insn badret_prog[] = {
130313498Sngie	BPF_STMT(BPF_RET+BPF_A+0x8000, 0),
131313498Sngie};
132313498Sngie
133272343Sngiestatic uint16_t
134272343Sngiein_cksum(void *data, size_t len)
135272343Sngie{
136272343Sngie	uint16_t *buf = data;
137272343Sngie	unsigned sum;
138272343Sngie
139272343Sngie	for (sum = 0; len > 1; len -= 2)
140272343Sngie		sum += *buf++;
141272343Sngie	if (len)
142272343Sngie		sum += *(uint8_t *)buf;
143272343Sngie
144272343Sngie	sum = (sum >> 16) + (sum & 0xffff);
145272343Sngie	sum += (sum >> 16);
146272343Sngie
147272343Sngie	return ~sum;
148272343Sngie}
149272343Sngie
150272343Sngie/*
151272343Sngie * Based on netcfg_rump_pingtest().
152272343Sngie */
153272343Sngiestatic bool __unused
154272343Sngiepingtest(const char *dst, unsigned int wirelen, const char tail[7])
155272343Sngie{
156272343Sngie	struct timeval tv;
157272343Sngie	struct sockaddr_in sin;
158272343Sngie	struct icmp *icmp;
159272343Sngie	char *pkt;
160272343Sngie	unsigned int pktsize;
161272343Sngie	socklen_t slen;
162272343Sngie	int s;
163272343Sngie	bool rv = false;
164272343Sngie
165272343Sngie	if (wirelen < ETHER_HDR_LEN + sizeof(struct ip))
166272343Sngie		return false;
167272343Sngie
168272343Sngie	pktsize = wirelen - ETHER_HDR_LEN - sizeof(struct ip);
169272343Sngie	if (pktsize < sizeof(struct icmp) + 7)
170272343Sngie		return false;
171272343Sngie
172272343Sngie	s = rump_sys_socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
173272343Sngie	if (s == -1)
174272343Sngie		return false;
175272343Sngie
176272343Sngie	pkt = NULL;
177272343Sngie
178272343Sngie	tv.tv_sec = 1;
179272343Sngie	tv.tv_usec = 0;
180272343Sngie	if (rump_sys_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
181272343Sngie	    &tv, sizeof(tv)) == -1)
182272343Sngie		goto out;
183272343Sngie
184272343Sngie	memset(&sin, 0, sizeof(sin));
185272343Sngie	sin.sin_len = sizeof(sin);
186272343Sngie	sin.sin_family = AF_INET;
187272343Sngie	sin.sin_addr.s_addr = inet_addr(dst);
188272343Sngie
189272343Sngie	pkt = calloc(1, pktsize);
190272343Sngie	icmp = (struct icmp *)pkt;
191272343Sngie	if (pkt == NULL)
192272343Sngie		goto out;
193272343Sngie
194272343Sngie	memcpy(pkt + pktsize - 7, tail, 7);
195272343Sngie	icmp->icmp_type = ICMP_ECHO;
196272343Sngie	icmp->icmp_id = htons(37);
197272343Sngie	icmp->icmp_seq = htons(1);
198272343Sngie	icmp->icmp_cksum = in_cksum(pkt, pktsize);
199272343Sngie
200272343Sngie	slen = sizeof(sin);
201272343Sngie	if (rump_sys_sendto(s, pkt, pktsize, 0,
202272343Sngie	    (struct sockaddr *)&sin, slen) == -1) {
203272343Sngie		goto out;
204272343Sngie	}
205272343Sngie
206272343Sngie	if (rump_sys_recvfrom(s, pkt, pktsize, 0,
207272343Sngie	    (struct sockaddr *)&sin, &slen) == -1)
208272343Sngie		goto out;
209272343Sngie
210272343Sngie	rv = true;
211272343Sngie out:
212272343Sngie	if (pkt != NULL)
213272343Sngie		free(pkt);
214272343Sngie	rump_sys_close(s);
215272343Sngie	return rv;
216272343Sngie}
217272343Sngie
218272343Sngiestatic void
219272343Sngiemagic_ping_test(const char *name, unsigned int wirelen)
220272343Sngie{
221272343Sngie	struct bpf_program prog;
222272343Sngie	struct bpf_stat bstat;
223272343Sngie	struct ifreq ifr;
224272343Sngie	struct timeval tv;
225272343Sngie	unsigned int bufsize;
226272343Sngie	bool pinged;
227272343Sngie	ssize_t n;
228272343Sngie	char *buf;
229272343Sngie	pid_t child;
230272343Sngie	int bpfd;
231272343Sngie	char token;
232272343Sngie	int channel[2];
233272343Sngie
234272343Sngie	struct bpf_hdr *hdr;
235272343Sngie
236272343Sngie	RL(pipe(channel));
237272343Sngie
238272343Sngie	prog.bf_len = __arraycount(magic_echo_reply_prog);
239272343Sngie	prog.bf_insns = magic_echo_reply_prog;
240272343Sngie
241272343Sngie	child = fork();
242272343Sngie	RZ(rump_init());
243272343Sngie	netcfg_rump_makeshmif(name, ifr.ifr_name);
244272343Sngie
245272343Sngie	switch (child) {
246272343Sngie	case -1:
247272343Sngie		atf_tc_fail_errno("fork failed");
248272343Sngie	case 0:
249272343Sngie		netcfg_rump_if(ifr.ifr_name, "10.1.1.10", "255.0.0.0");
250272343Sngie		close(channel[0]);
251272343Sngie		ATF_CHECK(write(channel[1], "U", 1) == 1);
252272343Sngie		close(channel[1]);
253272343Sngie		pause();
254272343Sngie		return;
255272343Sngie	default:
256272343Sngie		break;
257272343Sngie	}
258272343Sngie
259272343Sngie	netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0");
260272343Sngie
261272343Sngie	RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY));
262272343Sngie
263272343Sngie	tv.tv_sec = 0;
264272343Sngie	tv.tv_usec = 500;
265272343Sngie	RL(rump_sys_ioctl(bpfd, BIOCSRTIMEOUT, &tv));
266272343Sngie
267272343Sngie	RL(rump_sys_ioctl(bpfd, BIOCGBLEN, &bufsize));
268272343Sngie	RL(rump_sys_ioctl(bpfd, BIOCSETF, &prog));
269272343Sngie	RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr));
270272343Sngie
271272343Sngie	close(channel[1]);
272272343Sngie	ATF_CHECK(read(channel[0], &token, 1) == 1 && token == 'U');
273272343Sngie
274272343Sngie	pinged = pingtest("10.1.1.10", wirelen, magic_echo_reply_tail);
275272343Sngie	ATF_CHECK(pinged);
276272343Sngie
277272343Sngie	buf = malloc(bufsize);
278272343Sngie	hdr = (struct bpf_hdr *)buf;
279272343Sngie	ATF_REQUIRE(buf != NULL);
280272343Sngie	ATF_REQUIRE(bufsize > sizeof(struct bpf_hdr));
281272343Sngie
282272343Sngie	n = rump_sys_read(bpfd, buf, bufsize);
283272343Sngie
284272343Sngie	ATF_CHECK(n > (int)sizeof(struct bpf_hdr));
285272343Sngie	ATF_CHECK(hdr->bh_caplen == MIN(SNAPLEN, wirelen));
286272343Sngie
287272343Sngie	RL(rump_sys_ioctl(bpfd, BIOCGSTATS, &bstat));
288272343Sngie	ATF_CHECK(bstat.bs_capt >= 1); /* XXX == 1 */
289272343Sngie
290272343Sngie	rump_sys_close(bpfd);
291272343Sngie	free(buf);
292272343Sngie
293272343Sngie	close(channel[0]);
294272343Sngie
295272343Sngie	kill(child, SIGKILL);
296272343Sngie}
297272343Sngie
298272343Sngiestatic int
299272343Sngiesend_bpf_prog(const char *ifname, struct bpf_program *prog)
300272343Sngie{
301272343Sngie	struct ifreq ifr;
302272343Sngie	int bpfd, e, rv;
303272343Sngie
304272343Sngie	RZ(rump_init());
305272343Sngie	netcfg_rump_makeshmif(ifname, ifr.ifr_name);
306272343Sngie	netcfg_rump_if(ifr.ifr_name, "10.1.1.20", "255.0.0.0");
307272343Sngie
308272343Sngie	RL(bpfd = rump_sys_open("/dev/bpf", O_RDONLY));
309272343Sngie
310272343Sngie	rv = rump_sys_ioctl(bpfd, BIOCSETF, prog);
311272343Sngie	e = errno;
312272343Sngie
313272343Sngie	rump_sys_close(bpfd);
314272343Sngie	errno = e;
315272343Sngie
316272343Sngie	return rv;
317272343Sngie}
318272343Sngie
319272343SngieATF_TC(bpfiltercontig);
320272343SngieATF_TC_HEAD(bpfiltercontig, tc)
321272343Sngie{
322272343Sngie
323272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program "
324272343Sngie	    "can read bytes from contiguous buffer.");
325272343Sngie	atf_tc_set_md_var(tc, "timeout", "30");
326272343Sngie}
327272343Sngie
328272343SngieATF_TC_BODY(bpfiltercontig, tc)
329272343Sngie{
330272343Sngie
331272343Sngie	magic_ping_test("bpfiltercontig", 128);
332272343Sngie}
333272343Sngie
334272343Sngie
335272343SngieATF_TC(bpfiltermchain);
336272343SngieATF_TC_HEAD(bpfiltermchain, tc)
337272343Sngie{
338272343Sngie
339272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program "
340272343Sngie	    "can read bytes from mbuf chain.");
341272343Sngie	atf_tc_set_md_var(tc, "timeout", "30");
342272343Sngie}
343272343Sngie
344272343SngieATF_TC_BODY(bpfiltermchain, tc)
345272343Sngie{
346272343Sngie
347272343Sngie	magic_ping_test("bpfiltermchain", MINCLSIZE + 1);
348272343Sngie}
349272343Sngie
350272343Sngie
351272343SngieATF_TC(bpfilterbadmem);
352272343SngieATF_TC_HEAD(bpfilterbadmem, tc)
353272343Sngie{
354272343Sngie
355272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
356272343Sngie	    "doesn't initialize memomy store is rejected by the kernel");
357272343Sngie	atf_tc_set_md_var(tc, "timeout", "30");
358272343Sngie}
359272343Sngie
360272343SngieATF_TC_BODY(bpfilterbadmem, tc)
361272343Sngie{
362272343Sngie	struct bpf_program prog;
363272343Sngie
364272343Sngie	prog.bf_len = __arraycount(badmem_prog);
365272343Sngie	prog.bf_insns = badmem_prog;
366272343Sngie	ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadmem", &prog) == -1);
367272343Sngie}
368272343Sngie
369272343SngieATF_TC(bpfilternoinitA);
370272343SngieATF_TC_HEAD(bpfilternoinitA, tc)
371272343Sngie{
372272343Sngie
373272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
374272343Sngie	    "doesn't initialize the A register is accepted by the kernel");
375272343Sngie	atf_tc_set_md_var(tc, "timeout", "30");
376272343Sngie}
377272343Sngie
378272343SngieATF_TC_BODY(bpfilternoinitA, tc)
379272343Sngie{
380272343Sngie	struct bpf_program prog;
381272343Sngie
382272343Sngie	prog.bf_len = __arraycount(noinitA_prog);
383272343Sngie	prog.bf_insns = noinitA_prog;
384272343Sngie	RL(send_bpf_prog("bpfilternoinitA", &prog));
385272343Sngie}
386272343Sngie
387272343SngieATF_TC(bpfilternoinitX);
388272343SngieATF_TC_HEAD(bpfilternoinitX, tc)
389272343Sngie{
390272343Sngie
391272343Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
392272343Sngie	    "doesn't initialize the X register is accepted by the kernel");
393272343Sngie	atf_tc_set_md_var(tc, "timeout", "30");
394272343Sngie}
395272343Sngie
396272343SngieATF_TC_BODY(bpfilternoinitX, tc)
397272343Sngie{
398272343Sngie	struct bpf_program prog;
399272343Sngie
400272343Sngie	prog.bf_len = __arraycount(noinitX_prog);
401272343Sngie	prog.bf_insns = noinitX_prog;
402272343Sngie	RL(send_bpf_prog("bpfilternoinitX", &prog));
403272343Sngie}
404272343Sngie
405313498SngieATF_TC(bpfilterbadjmp);
406313498SngieATF_TC_HEAD(bpfilterbadjmp, tc)
407313498Sngie{
408313498Sngie
409313498Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
410313498Sngie	    "jumps to invalid destination is rejected by the kernel");
411313498Sngie	atf_tc_set_md_var(tc, "timeout", "30");
412313498Sngie}
413313498Sngie
414313498SngieATF_TC_BODY(bpfilterbadjmp, tc)
415313498Sngie{
416313498Sngie	struct bpf_program prog;
417313498Sngie
418313498Sngie	prog.bf_len = __arraycount(badjmp_prog);
419313498Sngie	prog.bf_insns = badjmp_prog;
420313498Sngie	ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadjmp", &prog) == -1);
421313498Sngie}
422313498Sngie
423313498SngieATF_TC(bpfilternegjmp);
424313498SngieATF_TC_HEAD(bpfilternegjmp, tc)
425313498Sngie{
426313498Sngie
427313498Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
428313498Sngie	    "jumps backwards is rejected by the kernel");
429313498Sngie	atf_tc_set_md_var(tc, "timeout", "30");
430313498Sngie}
431313498Sngie
432313498SngieATF_TC_BODY(bpfilternegjmp, tc)
433313498Sngie{
434313498Sngie	struct bpf_program prog;
435313498Sngie
436313498Sngie	prog.bf_len = __arraycount(negjmp_prog);
437313498Sngie	prog.bf_insns = negjmp_prog;
438313498Sngie	ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilternegjmp", &prog) == -1);
439313498Sngie}
440313498Sngie
441313498SngieATF_TC(bpfilterbadret);
442313498SngieATF_TC_HEAD(bpfilterbadret, tc)
443313498Sngie{
444313498Sngie
445313498Sngie	atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
446313498Sngie	    "ends with invalid BPF_RET instruction is rejected by the kernel");
447313498Sngie	atf_tc_set_md_var(tc, "timeout", "30");
448313498Sngie}
449313498Sngie
450313498SngieATF_TC_BODY(bpfilterbadret, tc)
451313498Sngie{
452313498Sngie	struct bpf_program prog;
453313498Sngie	struct bpf_insn *last;
454313498Sngie
455313498Sngie	prog.bf_len = __arraycount(badret_prog);
456313498Sngie	prog.bf_insns = badret_prog;
457313498Sngie
458313498Sngie	/*
459313498Sngie	 * The point of this test is checking a bad instruction of
460313498Sngie	 * a valid class and with a valid BPF_RVAL data.
461313498Sngie	 */
462313498Sngie	last = &prog.bf_insns[prog.bf_len - 1];
463313498Sngie	ATF_CHECK(BPF_CLASS(last->code) == BPF_RET &&
464313498Sngie	    (BPF_RVAL(last->code) == BPF_K || BPF_RVAL(last->code) == BPF_A));
465313498Sngie
466313498Sngie	ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadret", &prog) == -1);
467313498Sngie}
468313498Sngie
469272343SngieATF_TP_ADD_TCS(tp)
470272343Sngie{
471272343Sngie
472272343Sngie	ATF_TP_ADD_TC(tp, bpfiltercontig);
473272343Sngie	ATF_TP_ADD_TC(tp, bpfiltermchain);
474272343Sngie	ATF_TP_ADD_TC(tp, bpfilterbadmem);
475272343Sngie	ATF_TP_ADD_TC(tp, bpfilternoinitA);
476272343Sngie	ATF_TP_ADD_TC(tp, bpfilternoinitX);
477313498Sngie	ATF_TP_ADD_TC(tp, bpfilterbadjmp);
478313498Sngie	ATF_TP_ADD_TC(tp, bpfilternegjmp);
479313498Sngie	ATF_TP_ADD_TC(tp, bpfilterbadret);
480272343Sngie
481272343Sngie	return atf_no_error();
482272343Sngie}
483