diff options
-rw-r--r-- | regress/sys/kern/kqueue/Makefile | 19 | ||||
-rw-r--r-- | regress/sys/kern/kqueue/kqueue-tun.c | 168 | ||||
-rw-r--r-- | regress/sys/kern/kqueue/main.c | 10 |
3 files changed, 189 insertions, 8 deletions
diff --git a/regress/sys/kern/kqueue/Makefile b/regress/sys/kern/kqueue/Makefile index d9f7896d0dd..5a8efbb6e79 100644 --- a/regress/sys/kern/kqueue/Makefile +++ b/regress/sys/kern/kqueue/Makefile @@ -1,11 +1,11 @@ -# $OpenBSD: Makefile,v 1.8 2003/06/15 16:41:34 mickey Exp $ +# $OpenBSD: Makefile,v 1.9 2003/12/02 05:48:48 mickey Exp $ PROG= kqueue-test CFLAGS+=-Wall SRCS= kqueue-pipe.c kqueue-fork.c main.c kqueue-process.c kqueue-random.c \ - kqueue-pty.c -LDADD= -lutil -DPADD= ${DPUTIL} + kqueue-pty.c kqueue-tun.c +LDADD= -levent -lutil +DPADD= ${LIBEVENT} ${LIBUTIL} kq-pipe: ${PROG} ./${PROG} -p @@ -15,10 +15,19 @@ kq-process: ${PROG} ./${PROG} -P kq-random: ${PROG} ./${PROG} -r +kq-tun: ${PROG} + @EVENT_SHOW_METHOD=yes EVENT_NOKQUEUE=yes ${SUDO} ./${PROG} -t + @EVENT_SHOW_METHOD=yes EVENT_NOSELECT=yes ${SUDO} ./${PROG} -t + @${SUDO} ifconfig tun0 -alias down + @${SUDO} ifconfig tun1 -alias down kq-pty: ${PROG} ${SUDO} ./${PROG} -T -REGRESS_TARGETS=kq-pipe kq-fork kq-process kq-random kq-pty +REGRESS_TARGETS=kq-pipe kq-fork kq-process kq-random kq-tun kq-pty .PHONY: ${REGRESS_TARGETS} +clean: + @${SUDO} ifconfig tun0 -alias down + @${SUDO} ifconfig tun1 -alias down + .include <bsd.regress.mk> diff --git a/regress/sys/kern/kqueue/kqueue-tun.c b/regress/sys/kern/kqueue/kqueue-tun.c new file mode 100644 index 00000000000..f799cbe8afe --- /dev/null +++ b/regress/sys/kern/kqueue/kqueue-tun.c @@ -0,0 +1,168 @@ +/* $Gateweaver: tunkq.c,v 1.2 2003/11/27 22:47:41 cmaxwell Exp $ */ +/* + * Copyright 2003 Christopher J. Maxwell <cmaxwell@themanor.net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> +#include <netinet/in.h> +#include <net/if.h> +#include <net/if_tun.h> +#include <errno.h> +#include <err.h> +#include <event.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#define TUN0_ADDR "172.16.0.1" +#define TUN1_ADDR "172.16.0.2" +#define TUN_MAXWAIT 5 +#define TUN_PINGDEL 1 + +struct buffer { + u_char *buf; + size_t len; + size_t a; +}; + +int state; +int tunfd[2]; +struct buffer tpkt; +u_char pktbuf[TUNMTU]; +struct event tunwev[2]; +struct timeval exittv = {TUN_MAXWAIT, 0}; + +void +tunnel_write(int fd, short which, void *arg) +{ + uint32_t type = htonl(AF_INET); + struct iovec iv[2]; + int rlen; + int fdkey = (fd == tunfd[0]) ? 0 : 1; + + iv[0].iov_base = &type; + iv[0].iov_len = sizeof(type); + iv[1].iov_base = tpkt.buf; + iv[1].iov_len = tpkt.len; + + state++; + if ((rlen = writev(fd, iv, 2)) > 0) + fprintf(stderr, "Tunnel %d wrote %d bytes\n", + fdkey, rlen - sizeof(type)); + else + errx(1, "Read from tunnel %d failed", fdkey); +} + +void +tunnel_read(int fd, short which, void *arg) +{ + struct iovec iv[2]; + uint32_t type; + int rlen; + int fdkey = (fd == tunfd[0]) ? 0 : 1; + int oppfdkey = (fd == tunfd[0]) ? 1 : 0; + + iv[0].iov_base = &type; + iv[0].iov_len = sizeof(type); + iv[1].iov_base = tpkt.buf; + iv[1].iov_len = tpkt.a; + + state++; + if ((rlen = readv(fd, iv, 2)) > 0) { + fprintf(stderr, "Tunnel %d read %d bytes\n", + fdkey, rlen - sizeof(type)); + tpkt.len = rlen - sizeof(type); + + /* add write event on opposite tunnel */ + event_add(&tunwev[oppfdkey], &exittv); + } else + errx(1, "Read from tunnel %d failed", fdkey); +} + +void +tunnel_ping(int fd, short which, void *arg) +{ + system("ping -c 1 -I " TUN0_ADDR " " TUN1_ADDR " >/dev/null &"); +} + +/* + * +------------+ +------------+ + * | tun0 | | tun1 | + * | 172.16.0.1 | | 172.16.0.2 | + * +------------+ +------------+ + * + * Set up both tunnel devices (tun0, tun1) + * This works because the routing table prefers the opposing end of the ptp + * interfaces. + * Set up one read and one write event per tunnel. + * The read events add the write event. + */ +int +do_tun(void) +{ + struct event tunrev[2]; + struct event pingev; + struct timeval pingtv = {TUN_PINGDEL, 0}; + + /* read buffer */ + tpkt.buf = (u_char *)&pktbuf; + tpkt.len = 0; + tpkt.a = sizeof(pktbuf); + + event_init(); + + /* tun0 */ + if ((tunfd[0] = open("/dev/tun0", O_RDWR)) < 0) + errx(1, "Cannot open /dev/tun0"); + event_set(&tunrev[0], tunfd[0], EV_READ, tunnel_read, NULL); + event_set(&tunwev[0], tunfd[0], EV_WRITE, tunnel_write, NULL); + event_add(&tunrev[0], &exittv); + + /* tun1 */ + if ((tunfd[1] = open("/dev/tun1", O_RDWR)) < 0) + errx(1, "Cannot open /dev/tun1"); + event_set(&tunrev[1], tunfd[1], EV_READ, tunnel_read, NULL); + event_set(&tunwev[1], tunfd[1], EV_WRITE, tunnel_write, NULL); + event_add(&tunrev[1], &exittv); + + /* ping */ + evtimer_set(&pingev, tunnel_ping, NULL); + event_add(&pingev, &pingtv); + + /* configure the interfaces */ + system("ifconfig tun0 " TUN0_ADDR + " netmask 255.255.255.255 " TUN1_ADDR); + system("ifconfig tun1 " TUN1_ADDR + " netmask 255.255.255.255 " TUN0_ADDR); + + state = 0; + if (event_dispatch() < 0) + errx(errno, "Event handler failed"); + + return (state != 4); +} diff --git a/regress/sys/kern/kqueue/main.c b/regress/sys/kern/kqueue/main.c index 3e19f26a685..d51ebb00304 100644 --- a/regress/sys/kern/kqueue/main.c +++ b/regress/sys/kern/kqueue/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.4 2003/06/12 05:06:47 mickey Exp $ */ +/* $OpenBSD: main.c,v 1.5 2003/12/02 05:48:48 mickey Exp $ */ /* * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain */ @@ -12,6 +12,7 @@ int check_inheritance(void); int do_process(void); int do_random(void); int do_pty(void); +int do_tun(void); int main(int argc, char **argv) @@ -20,7 +21,7 @@ main(int argc, char **argv) int ret, c; ret = 0; - while ((c = getopt(argc, argv, "fPprT")) != -1) { + while ((c = getopt(argc, argv, "fPprTt")) != -1) { switch (c) { case 'p': ret |= do_pipe(); @@ -34,11 +35,14 @@ main(int argc, char **argv) case 'r': ret |= do_random(); break; + case 't': + ret |= do_tun(); + break; case 'T': ret |= do_pty(); break; default: - fprintf(stderr, "Usage: %s -[fPprt]\n", __progname); + fprintf(stderr, "Usage: %s -[fPprTt]\n", __progname); exit(1); } } |