summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/net
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/net')
-rwxr-xr-xcontrib/netbsd-tests/net/arp/t_arp.sh612
-rwxr-xr-xcontrib/netbsd-tests/net/arp/t_dad.sh201
-rw-r--r--contrib/netbsd-tests/net/bpfilter/t_bpfilter.c86
-rw-r--r--contrib/netbsd-tests/net/bpfjit/t_bpfjit.c756
-rw-r--r--contrib/netbsd-tests/net/icmp/t_forward.c6
-rwxr-xr-xcontrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh152
-rwxr-xr-xcontrib/netbsd-tests/net/icmp/t_icmp_redirect.sh285
-rw-r--r--contrib/netbsd-tests/net/icmp/t_ping.c8
-rwxr-xr-xcontrib/netbsd-tests/net/icmp/t_ping2.sh4
-rw-r--r--contrib/netbsd-tests/net/if/ifconf.c134
-rw-r--r--contrib/netbsd-tests/net/if/t_compat.c4
-rwxr-xr-xcontrib/netbsd-tests/net/if/t_ifconf.sh100
-rwxr-xr-xcontrib/netbsd-tests/net/if/t_ifconfig.sh333
-rwxr-xr-xcontrib/netbsd-tests/net/if_bridge/t_bridge.sh409
-rwxr-xr-xcontrib/netbsd-tests/net/if_gif/t_gif.sh763
-rwxr-xr-xcontrib/netbsd-tests/net/if_pppoe/t_pppoe.sh416
-rwxr-xr-xcontrib/netbsd-tests/net/if_tap/t_tap.sh198
-rw-r--r--contrib/netbsd-tests/net/in_cksum/assym.h10
-rw-r--r--contrib/netbsd-tests/net/in_cksum/in_cksum.c270
-rwxr-xr-xcontrib/netbsd-tests/net/in_cksum/t_in_cksum.sh78
-rw-r--r--contrib/netbsd-tests/net/mcast/mcast.c559
-rwxr-xr-xcontrib/netbsd-tests/net/mcast/t_mcast.sh106
-rwxr-xr-xcontrib/netbsd-tests/net/mpls/t_ldp_regen.sh11
-rwxr-xr-xcontrib/netbsd-tests/net/mpls/t_mpls_fw.sh6
-rwxr-xr-xcontrib/netbsd-tests/net/mpls/t_mpls_fw6.sh220
-rwxr-xr-xcontrib/netbsd-tests/net/mpls/t_mpls_fw64.sh226
-rwxr-xr-xcontrib/netbsd-tests/net/mpls/t_rfc4182.sh6
-rwxr-xr-xcontrib/netbsd-tests/net/ndp/t_dad.sh276
-rwxr-xr-xcontrib/netbsd-tests/net/ndp/t_ndp.sh406
-rwxr-xr-xcontrib/netbsd-tests/net/ndp/t_ra.sh687
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_forwarding.sh530
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_ipaddress.sh193
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_ipv6_lifetime.sh127
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_ipv6address.sh387
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_mtudisc.sh192
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_mtudisc6.sh179
-rwxr-xr-xcontrib/netbsd-tests/net/net/t_ping6_opts.sh380
-rw-r--r--contrib/netbsd-tests/net/net/t_tcp.c15
-rwxr-xr-xcontrib/netbsd-tests/net/net_common.sh314
-rwxr-xr-xcontrib/netbsd-tests/net/route/t_change.sh255
-rwxr-xr-xcontrib/netbsd-tests/net/route/t_flags.sh334
-rwxr-xr-xcontrib/netbsd-tests/net/route/t_flags6.sh268
-rwxr-xr-xcontrib/netbsd-tests/net/route/t_route.sh406
43 files changed, 10778 insertions, 130 deletions
diff --git a/contrib/netbsd-tests/net/arp/t_arp.sh b/contrib/netbsd-tests/net/arp/t_arp.sh
new file mode 100755
index 0000000..04e2f70
--- /dev/null
+++ b/contrib/netbsd-tests/net/arp/t_arp.sh
@@ -0,0 +1,612 @@
+# $NetBSD: t_arp.sh,v 1.22 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKSRC=unix://commsock1
+SOCKDST=unix://commsock2
+IP4SRC=10.0.1.1
+IP4DST=10.0.1.2
+IP4DST_PROXYARP1=10.0.1.3
+IP4DST_PROXYARP2=10.0.1.4
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=1
+
+atf_test_case arp_cache_expiration_5s cleanup
+atf_test_case arp_cache_expiration_10s cleanup
+atf_test_case arp_command cleanup
+atf_test_case arp_garp cleanup
+atf_test_case arp_cache_overwriting cleanup
+atf_test_case arp_proxy_arp_pub cleanup
+atf_test_case arp_proxy_arp_pubproxy cleanup
+atf_test_case arp_link_activation cleanup
+atf_test_case arp_static cleanup
+
+arp_cache_expiration_5s_head()
+{
+ atf_set "descr" "Tests for ARP cache expiration (5s)"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_cache_expiration_10s_head()
+{
+ atf_set "descr" "Tests for ARP cache expiration (10s)"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_command_head()
+{
+ atf_set "descr" "Tests for arp_commands of arp(8)"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_garp_head()
+{
+ atf_set "descr" "Tests for GARP"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_cache_overwriting_head()
+{
+ atf_set "descr" "Tests for behavior of overwriting ARP caches"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_proxy_arp_pub_head()
+{
+ atf_set "descr" "Tests for Proxy ARP (pub)"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_proxy_arp_pubproxy_head()
+{
+ atf_set "descr" "Tests for Proxy ARP (pub proxy)"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_link_activation_head()
+{
+ atf_set "descr" "Tests for activating a new MAC address"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_static_head()
+{
+
+ atf_set "descr" "Tests for static ARP entries"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_dst_server()
+{
+
+ rump_server_add_iface $SOCKDST shmif0 bus1
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4DST/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig shmif0
+ $DEBUG && rump.arp -n -a
+}
+
+setup_src_server()
+{
+ local keep=$1
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # Adjust ARP parameters
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.arp.keep=$keep
+
+ # Setup an interface
+ rump_server_add_iface $SOCKSRC shmif0 bus1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet $IP4SRC/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ # Sanity check
+ $DEBUG && rump.ifconfig shmif0
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
+ atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST
+}
+
+test_cache_expiration()
+{
+ local arp_keep=$1
+ local bonus=2
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ #
+ # Check if a cache is expired expectedly
+ #
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
+
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
+ # Should be cached
+ atf_check -s exit:0 -o ignore rump.arp -n $IP4DST
+
+ atf_check -s exit:0 sleep $(($arp_keep + $bonus))
+
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -n $IP4SRC
+ # Should be expired
+ atf_check -s not-exit:0 -e ignore rump.arp -n $IP4DST
+}
+
+arp_cache_expiration_5s_body()
+{
+
+ test_cache_expiration 5
+ rump_server_destroy_ifaces
+}
+
+arp_cache_expiration_10s_body()
+{
+
+ test_cache_expiration 10
+ rump_server_destroy_ifaces
+}
+
+arp_command_body()
+{
+ local arp_keep=5
+ local bonus=2
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # We can delete the entry for the interface's IP address
+ atf_check -s exit:0 -o ignore rump.arp -d $IP4SRC
+
+ # Add and delete a static entry
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.10
+ atf_check -s exit:0 -o ignore rump.arp -d 10.0.1.10
+ $DEBUG && rump.arp -n -a
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
+
+ # Add multiple entries via a file
+ cat - > ./list <<-EOF
+ 10.0.1.11 b2:a0:20:00:00:11
+ 10.0.1.12 b2:a0:20:00:00:12
+ 10.0.1.13 b2:a0:20:00:00:13
+ 10.0.1.14 b2:a0:20:00:00:14
+ 10.0.1.15 b2:a0:20:00:00:15
+ EOF
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -f ./list
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:11' rump.arp -n 10.0.1.11
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.11
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:12' rump.arp -n 10.0.1.12
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.12
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:13' rump.arp -n 10.0.1.13
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.13
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:14' rump.arp -n 10.0.1.14
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.14
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:15' rump.arp -n 10.0.1.15
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n 10.0.1.15
+
+ # Test arp -a
+ atf_check -s exit:0 -o match:'10.0.1.11' rump.arp -n -a
+ atf_check -s exit:0 -o match:'10.0.1.12' rump.arp -n -a
+ atf_check -s exit:0 -o match:'10.0.1.13' rump.arp -n -a
+ atf_check -s exit:0 -o match:'10.0.1.14' rump.arp -n -a
+ atf_check -s exit:0 -o match:'10.0.1.15' rump.arp -n -a
+
+ # Flush all entries
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -d -a
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.11
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.12
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.13
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.14
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.15
+ atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.1
+
+ # Test temp option
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
+ atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10
+
+ # Hm? the cache doesn't expire...
+ atf_check -s exit:0 sleep $(($arp_keep + $bonus))
+ $DEBUG && rump.arp -n -a
+ #atf_check -s not-exit:0 -e ignore rump.arp -n 10.0.1.10
+
+ rump_server_destroy_ifaces
+}
+
+make_pkt_str_arpreq()
+{
+ local target=$1
+ local sender=$2
+ pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:"
+ pkt="$pkt Request who-has $target tell $sender, length 28"
+ echo $pkt
+}
+
+arp_garp_body()
+{
+ local pkt=
+
+ rump_server_start $SOCKSRC
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # Setup an interface
+ rump_server_add_iface $SOCKSRC shmif0 bus1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ $DEBUG && rump.ifconfig shmif0
+
+ atf_check -s exit:0 sleep 1
+ shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out
+
+ # A GARP packet is sent for the primary address
+ pkt=$(make_pkt_str_arpreq 10.0.0.1 10.0.0.1)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+ # No GARP packet is sent for the alias address
+ pkt=$(make_pkt_str_arpreq 10.0.0.2 10.0.0.2)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ atf_check -s exit:0 rump.ifconfig -w 10
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.4/24 alias
+
+ # No GARP packets are sent during IFF_UP
+ shmif_dumpbus -p - bus1 2>/dev/null| tcpdump -n -e -r - > ./out
+ pkt=$(make_pkt_str_arpreq 10.0.0.3 10.0.0.3)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+ pkt=$(make_pkt_str_arpreq 10.0.0.4 10.0.0.4)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ rump_server_destroy_ifaces
+}
+
+arp_cache_overwriting_body()
+{
+ local arp_keep=5
+ local bonus=2
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # Cannot overwrite a permanent cache
+ atf_check -s not-exit:0 -e match:'File exists' \
+ rump.arp -s $IP4SRC b2:a0:20:00:00:ff
+ $DEBUG && rump.arp -n -a
+
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4DST
+ $DEBUG && rump.arp -n -a
+ # Can overwrite a dynamic cache
+ atf_check -s exit:0 -o ignore rump.arp -s $IP4DST b2:a0:20:00:00:00
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:00' rump.arp -n $IP4DST
+ atf_check -s exit:0 -o match:'permanent' rump.arp -n $IP4DST
+
+ atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:10 temp
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:10' rump.arp -n 10.0.1.10
+ atf_check -s exit:0 -o not-match:'permanent' rump.arp -n 10.0.1.10
+ # Can overwrite a temp cache
+ atf_check -s exit:0 -o ignore rump.arp -s 10.0.1.10 b2:a0:20:00:00:ff
+ atf_check -s exit:0 -o match:'b2:a0:20:00:00:ff' rump.arp -n 10.0.1.10
+ $DEBUG && rump.arp -n -a
+
+ rump_server_destroy_ifaces
+}
+
+make_pkt_str_arprep()
+{
+ local ip=$1
+ local mac=$2
+ pkt="ethertype ARP (0x0806), length 42: "
+ pkt="Reply $ip is-at $mac, length 28"
+ echo $pkt
+}
+
+make_pkt_str_garp()
+{
+ local ip=$1
+ local mac=$2
+ local pkt=
+ pkt="$mac > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806),"
+ pkt="$pkt length 42: Request who-has $ip tell $ip, length 28"
+ echo $pkt
+}
+
+test_proxy_arp()
+{
+ local arp_keep=5
+ local opts= title= flags=
+ local type=$1
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST tap
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1
+ macaddr_dst=$(get_macaddr $SOCKDST shmif0)
+
+ if [ "$type" = "pub" ]; then
+ opts="pub"
+ title="permanent published"
+ else
+ opts="pub proxy"
+ title='permanent published \(proxy only\)'
+ fi
+
+ #
+ # Test#1: First setup an endpoint then create proxy arp entry
+ #
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 rump.ifconfig tap1 create
+ atf_check -s exit:0 rump.ifconfig tap1 $IP4DST_PROXYARP1/24 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ # Try to ping (should fail w/o proxy arp)
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1
+
+ # Flushing
+ extract_new_packets bus1 > ./out
+
+ # Set up proxy ARP entry
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore \
+ rump.arp -s $IP4DST_PROXYARP1 $macaddr_dst $opts
+ atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP1
+
+ # Try to ping
+ export RUMP_SERVER=$SOCKSRC
+ if [ "$type" = "pub" ]; then
+ # XXX fails
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1
+ else
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP1
+ fi
+
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ pkt1=$(make_pkt_str_arprep $IP4DST_PROXYARP1 $macaddr_dst)
+ pkt2=$(make_pkt_str_garp $IP4DST_PROXYARP1 $macaddr_dst)
+ if [ "$type" = "pub" ]; then
+ atf_check -s not-exit:0 -x \
+ "cat ./out |grep -q -e '$pkt1' -e '$pkt2'"
+ else
+ atf_check -s exit:0 -x "cat ./out |grep -q -e '$pkt1' -e '$pkt2'"
+ fi
+
+ #
+ # Test#2: Create proxy arp entry then set up an endpoint
+ #
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore \
+ rump.arp -s $IP4DST_PROXYARP2 $macaddr_dst $opts
+ atf_check -s exit:0 -o match:"$title" rump.arp -n $IP4DST_PROXYARP2
+ $DEBUG && rump.netstat -nr -f inet
+
+ # Try to ping (should fail because no endpoint exists)
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2
+
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # ARP reply should be sent
+ pkt=$(make_pkt_str_arprep $IP4DST_PROXYARP2 $macaddr_dst)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 rump.ifconfig tap2 create
+ atf_check -s exit:0 rump.ifconfig tap2 $IP4DST_PROXYARP2/24 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ # Try to ping
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST_PROXYARP2
+}
+
+arp_proxy_arp_pub_body()
+{
+
+ test_proxy_arp pub
+ rump_server_destroy_ifaces
+}
+
+arp_proxy_arp_pubproxy_body()
+{
+
+ test_proxy_arp pubproxy
+ rump_server_destroy_ifaces
+}
+
+arp_link_activation_body()
+{
+ local arp_keep=5
+ local bonus=2
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ # flush old packets
+ extract_new_packets bus1 > ./out
+
+ export RUMP_SERVER=$SOCKSRC
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
+ b2:a1:00:00:00:01
+
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
+ b2:a1:00:00:00:02 active
+
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ pkt=$(make_pkt_str_arpreq $IP4SRC $IP4SRC)
+ atf_check -s exit:0 -x \
+ "cat ./out |grep '$pkt' |grep -q 'b2:a1:00:00:00:02'"
+
+ rump_server_destroy_ifaces
+}
+
+arp_static_body()
+{
+ local arp_keep=5
+ local macaddr_src=
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server $arp_keep
+
+ macaddr_src=$(get_macaddr $SOCKSRC shmif0)
+
+ # Set a (valid) static ARP entry for the src server
+ export RUMP_SERVER=$SOCKDST
+ $DEBUG && rump.arp -n -a
+ atf_check -s exit:0 -o ignore rump.arp -s $IP4SRC $macaddr_src
+ $DEBUG && rump.arp -n -a
+
+ # Test receiving an ARP request with the static ARP entry (as spa/sha)
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
+
+ rump_server_destroy_ifaces
+}
+
+arp_cache_expiration_5s_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_cache_expiration_10s_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_command_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_garp_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_cache_overwriting_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_proxy_arp_pub_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_proxy_arp_pubproxy_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_link_activation_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+arp_static_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case arp_cache_expiration_5s
+ atf_add_test_case arp_cache_expiration_10s
+ atf_add_test_case arp_command
+ atf_add_test_case arp_garp
+ atf_add_test_case arp_cache_overwriting
+ atf_add_test_case arp_proxy_arp_pub
+ atf_add_test_case arp_proxy_arp_pubproxy
+ atf_add_test_case arp_link_activation
+ atf_add_test_case arp_static
+}
diff --git a/contrib/netbsd-tests/net/arp/t_dad.sh b/contrib/netbsd-tests/net/arp/t_dad.sh
new file mode 100755
index 0000000..57a7d4b0
--- /dev/null
+++ b/contrib/netbsd-tests/net/arp/t_dad.sh
@@ -0,0 +1,201 @@
+# $NetBSD: t_dad.sh,v 1.13 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKLOCAL=unix://commsock1
+SOCKPEER=unix://commsock2
+
+DEBUG=${DEBUG:-false}
+
+atf_test_case dad_basic cleanup
+atf_test_case dad_duplicated cleanup
+
+dad_basic_head()
+{
+ atf_set "descr" "Tests for IPv4 DAD basic behavior"
+ atf_set "require.progs" "rump_server"
+}
+
+dad_duplicated_head()
+{
+ atf_set "descr" "Tests for IPv4 DAD duplicated state"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_server()
+{
+ local sock=$1
+ local ip=$2
+
+ rump_server_add_iface $sock shmif0 bus1
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig shmif0 inet $ip/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig shmif0
+}
+
+make_pkt_str()
+{
+ local target=$1
+ local sender=$2
+ pkt="> ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42:"
+ pkt="$pkt Request who-has $target tell $sender, length 28"
+ echo $pkt
+}
+
+dad_basic_body()
+{
+ local pkt=
+
+ rump_server_start $SOCKLOCAL
+ rump_server_add_iface $SOCKLOCAL shmif0 bus1
+
+ export RUMP_SERVER=$SOCKLOCAL
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.1/24
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.2/24 alias
+ $DEBUG && rump.ifconfig shmif0
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ rump.ifconfig shmif0 > ./out
+ $DEBUG && cat ./out
+
+ # The primary address doesn't start with tentative state
+ atf_check -s not-exit:0 -x "cat ./out |grep 10.0.0.1 |grep -iq tentative"
+ # The alias address starts with tentative state
+ # XXX we have no stable way to check this, so skip for now
+ #atf_check -s exit:0 -x "cat ./out |grep 10.0.0.2 |grep -iq tentative"
+
+ atf_check -s exit:0 sleep 2
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # Check DAD probe packets
+ pkt=$(make_pkt_str 10.0.0.2 0.0.0.0)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+ # No DAD for the primary address
+ pkt=$(make_pkt_str 10.0.0.1 0.0.0.0)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ # Waiting for DAD complete
+ atf_check -s exit:0 rump.ifconfig -w 10
+ # Give a chance to send a DAD announce packet
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # Check the DAD announce packet
+ pkt=$(make_pkt_str 10.0.0.2 10.0.0.2)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+ # The alias address left tentative
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.2 |grep -iq tentative"
+
+ #
+ # Add a new address on the fly
+ #
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.0.3/24 alias
+
+ # The new address starts with tentative state
+ # XXX we have no stable way to check this, so skip for now
+ #atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.3 |grep -iq tentative"
+
+ # Check DAD probe packets
+ atf_check -s exit:0 sleep 2
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+ pkt=$(make_pkt_str 10.0.0.3 0.0.0.0)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ # Waiting for DAD complete
+ atf_check -s exit:0 rump.ifconfig -w 10
+ # Give a chance to send a DAD announce packet
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # Check the DAD announce packet
+ pkt=$(make_pkt_str 10.0.0.3 10.0.0.3)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+ # The new address left tentative
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep 10.0.0.3 |grep -iq tentative"
+
+ rump_server_destroy_ifaces
+}
+
+dad_duplicated_body()
+{
+ local localip1=10.0.1.1
+ local localip2=10.0.1.11
+ local peerip=10.0.1.2
+
+ rump_server_start $SOCKLOCAL
+ rump_server_start $SOCKPEER
+
+ setup_server $SOCKLOCAL $localip1
+ setup_server $SOCKPEER $peerip
+
+ export RUMP_SERVER=$SOCKLOCAL
+
+ # The primary address isn't marked as duplicated
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip1 |grep -iq duplicated"
+
+ #
+ # Add a new address duplicated with the peer server
+ #
+ atf_check -s exit:0 rump.ifconfig shmif0 inet $peerip alias
+ atf_check -s exit:0 sleep 1
+
+ # The new address is marked as duplicated
+ atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep $peerip |grep -iq duplicated"
+
+ # A unique address isn't marked as duplicated
+ atf_check -s exit:0 rump.ifconfig shmif0 inet $localip2 alias
+ atf_check -s exit:0 sleep 1
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip2 |grep -iq duplicated"
+
+ rump_server_destroy_ifaces
+}
+
+dad_basic_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+dad_duplicated_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case dad_basic
+ atf_add_test_case dad_duplicated
+}
diff --git a/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c b/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c
index 9d8d56f..460b43e 100644
--- a/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c
+++ b/contrib/netbsd-tests/net/bpfilter/t_bpfilter.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_bpfilter.c,v 1.8 2014/06/24 11:32:36 alnsn Exp $ */
+/* $NetBSD: t_bpfilter.c,v 1.10 2015/02/11 23:39:07 alnsn Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -25,7 +25,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_bpfilter.c,v 1.8 2014/06/24 11:32:36 alnsn Exp $");
+__RCSID("$NetBSD: t_bpfilter.c,v 1.10 2015/02/11 23:39:07 alnsn Exp $");
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -115,6 +115,21 @@ static struct bpf_insn noinitX_prog[] = {
BPF_STMT(BPF_RET+BPF_A, 0),
};
+static struct bpf_insn badjmp_prog[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 5),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+static struct bpf_insn negjmp_prog[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 0),
+ BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2
+ BPF_STMT(BPF_RET+BPF_A, 0),
+};
+
+static struct bpf_insn badret_prog[] = {
+ BPF_STMT(BPF_RET+BPF_A+0x8000, 0),
+};
+
static uint16_t
in_cksum(void *data, size_t len)
{
@@ -387,6 +402,70 @@ ATF_TC_BODY(bpfilternoinitX, tc)
RL(send_bpf_prog("bpfilternoinitX", &prog));
}
+ATF_TC(bpfilterbadjmp);
+ATF_TC_HEAD(bpfilterbadjmp, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
+ "jumps to invalid destination is rejected by the kernel");
+ atf_tc_set_md_var(tc, "timeout", "30");
+}
+
+ATF_TC_BODY(bpfilterbadjmp, tc)
+{
+ struct bpf_program prog;
+
+ prog.bf_len = __arraycount(badjmp_prog);
+ prog.bf_insns = badjmp_prog;
+ ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadjmp", &prog) == -1);
+}
+
+ATF_TC(bpfilternegjmp);
+ATF_TC_HEAD(bpfilternegjmp, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
+ "jumps backwards is rejected by the kernel");
+ atf_tc_set_md_var(tc, "timeout", "30");
+}
+
+ATF_TC_BODY(bpfilternegjmp, tc)
+{
+ struct bpf_program prog;
+
+ prog.bf_len = __arraycount(negjmp_prog);
+ prog.bf_insns = negjmp_prog;
+ ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilternegjmp", &prog) == -1);
+}
+
+ATF_TC(bpfilterbadret);
+ATF_TC_HEAD(bpfilterbadret, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that bpf program that "
+ "ends with invalid BPF_RET instruction is rejected by the kernel");
+ atf_tc_set_md_var(tc, "timeout", "30");
+}
+
+ATF_TC_BODY(bpfilterbadret, tc)
+{
+ struct bpf_program prog;
+ struct bpf_insn *last;
+
+ prog.bf_len = __arraycount(badret_prog);
+ prog.bf_insns = badret_prog;
+
+ /*
+ * The point of this test is checking a bad instruction of
+ * a valid class and with a valid BPF_RVAL data.
+ */
+ last = &prog.bf_insns[prog.bf_len - 1];
+ ATF_CHECK(BPF_CLASS(last->code) == BPF_RET &&
+ (BPF_RVAL(last->code) == BPF_K || BPF_RVAL(last->code) == BPF_A));
+
+ ATF_CHECK_ERRNO(EINVAL, send_bpf_prog("bpfilterbadret", &prog) == -1);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -395,6 +474,9 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bpfilterbadmem);
ATF_TP_ADD_TC(tp, bpfilternoinitA);
ATF_TP_ADD_TC(tp, bpfilternoinitX);
+ ATF_TP_ADD_TC(tp, bpfilterbadjmp);
+ ATF_TP_ADD_TC(tp, bpfilternegjmp);
+ ATF_TP_ADD_TC(tp, bpfilterbadret);
return atf_no_error();
}
diff --git a/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c b/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c
index a9f8f41..58db1e0 100644
--- a/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c
+++ b/contrib/netbsd-tests/net/bpfjit/t_bpfjit.c
@@ -1,7 +1,7 @@
-/* $NetBSD: t_bpfjit.c,v 1.2 2014/07/08 21:44:26 alnsn Exp $ */
+/* $NetBSD: t_bpfjit.c,v 1.11 2015/02/14 22:34:33 alnsn Exp $ */
/*-
- * Copyright (c) 2011-2012, 2014 Alexander Nasonov.
+ * Copyright (c) 2011-2012, 2014-2015 Alexander Nasonov.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_bpfjit.c,v 1.2 2014/07/08 21:44:26 alnsn Exp $");
+__RCSID("$NetBSD: t_bpfjit.c,v 1.11 2015/02/14 22:34:33 alnsn Exp $");
#include <sys/param.h>
#include <sys/mbuf.h>
@@ -79,15 +79,73 @@ ATF_TC_HEAD(bpfjit_empty, tc)
ATF_TC_BODY(bpfjit_empty, tc)
{
struct bpf_insn dummy;
- bpfjit_func_t fn;
+ bpfjit_func_t code;
RZ(rump_init());
+ ATF_CHECK(!prog_validate(&dummy, 0));
+
rump_schedule();
- fn = rumpns_bpfjit_generate_code(NULL, &dummy, 0);
+ code = rumpns_bpfjit_generate_code(NULL, &dummy, 0);
rump_unschedule();
- ATF_CHECK(fn == NULL);
+ ATF_CHECK(code == NULL);
+}
+
+ATF_TC(bpfjit_ret_k);
+ATF_TC_HEAD(bpfjit_ret_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of a trivial bpf program");
+}
+
+ATF_TC_BODY(bpfjit_ret_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_RET+BPF_K, 17)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 17);
+}
+
+ATF_TC(bpfjit_bad_ret_k);
+ATF_TC_HEAD(bpfjit_bad_ret_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that JIT compilation of a program with bad BPF_RET fails");
+}
+
+ATF_TC_BODY(bpfjit_bad_ret_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_RET+BPF_K+0x8000, 13)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ /*
+ * The point of this test is checking a bad instruction of
+ * a valid class and with a valid BPF_RVAL data.
+ */
+ const uint16_t rcode = insns[0].code;
+ ATF_CHECK(BPF_CLASS(rcode) == BPF_RET &&
+ (BPF_RVAL(rcode) == BPF_K || BPF_RVAL(rcode) == BPF_A));
+
+ RZ(rump_init());
+
+ ATF_CHECK(!prog_validate(insns, insn_count));
+
+ /* Current implementation generates code. */
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 13);
}
ATF_TC(bpfjit_alu_add_k);
@@ -364,6 +422,205 @@ ATF_TC_BODY(bpfjit_alu_div80000000_k, tc)
ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
}
+ATF_TC(bpfjit_alu_mod0_k);
+ATF_TC_HEAD(bpfjit_alu_mod0_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod0_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ //ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
+}
+
+ATF_TC(bpfjit_alu_mod1_k);
+ATF_TC_HEAD(bpfjit_alu_mod1_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=1");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod1_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 1),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
+}
+
+ATF_TC(bpfjit_alu_mod2_k);
+ATF_TC_HEAD(bpfjit_alu_mod2_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=2");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod2_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
+}
+
+ATF_TC(bpfjit_alu_mod4_k);
+ATF_TC_HEAD(bpfjit_alu_mod4_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=4");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod4_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3);
+}
+
+ATF_TC(bpfjit_alu_mod10_k);
+ATF_TC_HEAD(bpfjit_alu_mod10_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod10_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 9);
+}
+
+ATF_TC(bpfjit_alu_mod10000_k);
+ATF_TC_HEAD(bpfjit_alu_mod10000_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=10000");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod10000_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, 10000),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3849);
+}
+
+ATF_TC(bpfjit_alu_mod7609801_k);
+ATF_TC_HEAD(bpfjit_alu_mod7609801_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=7609801");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod7609801_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(7609801)),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3039531);
+}
+
+ATF_TC(bpfjit_alu_mod80000000_k);
+ATF_TC_HEAD(bpfjit_alu_mod80000000_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_K with k=0x80000000");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod80000000_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_K, UINT32_C(0x80000000)),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_C(0x7fffffde));
+}
+
ATF_TC(bpfjit_alu_and_k);
ATF_TC_HEAD(bpfjit_alu_and_k, tc)
{
@@ -414,6 +671,31 @@ ATF_TC_BODY(bpfjit_alu_or_k, tc)
ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
}
+ATF_TC(bpfjit_alu_xor_k);
+ATF_TC_HEAD(bpfjit_alu_xor_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_K");
+}
+
+ATF_TC_BODY(bpfjit_alu_xor_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f),
+ BPF_STMT(BPF_ALU+BPF_XOR+BPF_K, 0x0000b1e0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
+}
+
ATF_TC(bpfjit_alu_lsh_k);
ATF_TC_HEAD(bpfjit_alu_lsh_k, tc)
{
@@ -852,7 +1134,7 @@ ATF_TC_HEAD(bpfjit_alu_div80000000_x, tc)
ATF_TC_BODY(bpfjit_alu_div80000000_x, tc)
{
static struct bpf_insn insns[] = {
- BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX - 33),
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)),
BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
BPF_STMT(BPF_RET+BPF_A, 0)
@@ -868,6 +1150,213 @@ ATF_TC_BODY(bpfjit_alu_div80000000_x, tc)
ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
}
+ATF_TC(bpfjit_alu_mod0_x);
+ATF_TC_HEAD(bpfjit_alu_mod0_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod0_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
+}
+
+ATF_TC(bpfjit_alu_mod1_x);
+ATF_TC_HEAD(bpfjit_alu_mod1_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=1");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod1_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0);
+}
+
+ATF_TC(bpfjit_alu_mod2_x);
+ATF_TC_HEAD(bpfjit_alu_mod2_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=2");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod2_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 1);
+}
+
+ATF_TC(bpfjit_alu_mod4_x);
+ATF_TC_HEAD(bpfjit_alu_mod4_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=4");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod4_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3);
+}
+
+ATF_TC(bpfjit_alu_mod10_x);
+ATF_TC_HEAD(bpfjit_alu_mod10_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod10_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 9);
+}
+
+ATF_TC(bpfjit_alu_mod10000_x);
+ATF_TC_HEAD(bpfjit_alu_mod10000_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=10000");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod10000_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3849);
+}
+
+ATF_TC(bpfjit_alu_mod7609801_x);
+ATF_TC_HEAD(bpfjit_alu_mod7609801_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=7609801");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod7609801_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 3039531);
+}
+
+ATF_TC(bpfjit_alu_mod80000000_x);
+ATF_TC_HEAD(bpfjit_alu_mod80000000_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MOD+BPF_X with X=0x80000000");
+}
+
+ATF_TC_BODY(bpfjit_alu_mod80000000_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)),
+ BPF_STMT(BPF_ALU+BPF_MOD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_C(0x7fffffde));
+}
+
ATF_TC(bpfjit_alu_and_x);
ATF_TC_HEAD(bpfjit_alu_and_x, tc)
{
@@ -920,6 +1409,32 @@ ATF_TC_BODY(bpfjit_alu_or_x, tc)
ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
}
+ATF_TC(bpfjit_alu_xor_x);
+ATF_TC_HEAD(bpfjit_alu_xor_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_XOR+BPF_X");
+}
+
+ATF_TC_BODY(bpfjit_alu_xor_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead0f0f),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000b1e0),
+ BPF_STMT(BPF_ALU+BPF_XOR+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+ ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == 0xdeadbeef);
+}
+
ATF_TC(bpfjit_alu_lsh_x);
ATF_TC_HEAD(bpfjit_alu_lsh_x, tc)
{
@@ -1155,6 +1670,66 @@ ATF_TC_BODY(bpfjit_jmp_ja, tc)
ATF_CHECK(exec_prog(insns, insn_count, pkt, 1) == UINT32_MAX);
}
+ATF_TC(bpfjit_jmp_ja_invalid);
+ATF_TC_HEAD(bpfjit_jmp_ja_invalid, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test BPF_JMP+BPF_JA to invalid destination");
+}
+
+ATF_TC_BODY(bpfjit_jmp_ja_invalid, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 4),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ };
+
+ bpfjit_func_t code;
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(!prog_validate(insns, insn_count));
+
+ rump_schedule();
+ code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
+ rump_unschedule();
+ ATF_CHECK(code == NULL);
+}
+
+ATF_TC(bpfjit_jmp_ja_overflow);
+ATF_TC_HEAD(bpfjit_jmp_ja_overflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test BPF_JMP+BPF_JA with negative offset");
+}
+
+ATF_TC_BODY(bpfjit_jmp_ja_overflow, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 1),
+ BPF_STMT(BPF_RET+BPF_K, 777),
+ BPF_STMT(BPF_JMP+BPF_JA, UINT32_MAX - 1), // -2
+ BPF_STMT(BPF_RET+BPF_K, 0)
+ };
+
+ bpfjit_func_t code;
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ /* Jumps with negative offsets work only in userspace. */
+ ATF_CHECK(!prog_validate(insns, insn_count));
+
+ rump_schedule();
+ code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
+ rump_unschedule();
+ ATF_CHECK(code == NULL);
+}
+
ATF_TC(bpfjit_jmp_jgt_k);
ATF_TC_HEAD(bpfjit_jmp_jgt_k, tc)
{
@@ -1574,26 +2149,26 @@ ATF_TC_BODY(bpfjit_jmp_jeq_x, tc)
BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
- BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
- BPF_STMT(BPF_RET+BPF_K, 1),
- BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 3),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
- BPF_STMT(BPF_RET+BPF_K, 3),
BPF_STMT(BPF_RET+BPF_K, 4),
BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_RET+BPF_K, 6),
BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
- BPF_STMT(BPF_RET+BPF_K, 6),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 1, 0, 0),
BPF_STMT(BPF_RET+BPF_K, 7),
- BPF_STMT(BPF_RET+BPF_K, 8)
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 8),
+ BPF_STMT(BPF_RET+BPF_K, 9)
};
bpfjit_func_t code;
@@ -1610,14 +2185,14 @@ ATF_TC_BODY(bpfjit_jmp_jeq_x, tc)
rump_unschedule();
ATF_REQUIRE(code != NULL);
- ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
- ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
- ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
- ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
- ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
- ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
- ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
- ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 8);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 8);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 2);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 8);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 3);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 9);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 6);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 1);
rump_schedule();
rumpns_bpfjit_free_code(code);
@@ -1687,6 +2262,116 @@ ATF_TC_BODY(bpfjit_jmp_jset_x, tc)
rump_unschedule();
}
+ATF_TC(bpfjit_jmp_jeq_x_noinit_ax);
+ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_ax, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
+ "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A and X");
+}
+
+ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_ax, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 10),
+ BPF_STMT(BPF_RET+BPF_K, 11)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+
+ rump_schedule();
+ code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
+ rump_unschedule();
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 10);
+
+ rump_schedule();
+ rumpns_bpfjit_free_code(code);
+ rump_unschedule();
+}
+
+ATF_TC(bpfjit_jmp_jeq_x_noinit_a);
+ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_a, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
+ "of BPF_JMP+BPF_EQ+BPF_X with uninitialised A");
+}
+
+ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_a, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0), /* X > 0 */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 10),
+ BPF_STMT(BPF_RET+BPF_K, 11)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+
+ rump_schedule();
+ code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
+ rump_unschedule();
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 11);
+
+ rump_schedule();
+ rumpns_bpfjit_free_code(code);
+ rump_unschedule();
+}
+
+ATF_TC(bpfjit_jmp_jeq_x_noinit_x);
+ATF_TC_HEAD(bpfjit_jmp_jeq_x_noinit_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test JIT compilation "
+ "of BPF_JMP+BPF_EQ+BPF_X with uninitialised X");
+}
+
+ATF_TC_BODY(bpfjit_jmp_jeq_x_noinit_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_LEN, 0), /* A > 0 */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 10),
+ BPF_STMT(BPF_RET+BPF_K, 11)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ RZ(rump_init());
+
+ ATF_CHECK(prog_validate(insns, insn_count));
+
+ rump_schedule();
+ code = rumpns_bpfjit_generate_code(NULL, insns, insn_count);
+ rump_unschedule();
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 11);
+
+ rump_schedule();
+ rumpns_bpfjit_free_code(code);
+ rump_unschedule();
+}
+
ATF_TC(bpfjit_jmp_modulo_x);
ATF_TC_HEAD(bpfjit_jmp_modulo_x, tc)
{
@@ -3887,6 +4572,8 @@ ATF_TP_ADD_TCS(tp)
* to ../../lib/libbpfjit/t_bpfjit.c
*/
ATF_TP_ADD_TC(tp, bpfjit_empty);
+ ATF_TP_ADD_TC(tp, bpfjit_ret_k);
+ ATF_TP_ADD_TC(tp, bpfjit_bad_ret_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_add_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_sub_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_mul_k);
@@ -3898,8 +4585,17 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_and_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_or_k);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_xor_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_k);
ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_k);
@@ -3916,8 +4612,17 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bpfjit_alu_div10000_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_div7609801_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_div80000000_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod0_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod1_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod2_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod4_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod10_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod10000_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod7609801_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_mod80000000_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_and_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_or_x);
+ ATF_TP_ADD_TC(tp, bpfjit_alu_xor_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_lsh_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_lsh0_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_rsh_x);
@@ -3925,6 +4630,8 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bpfjit_alu_modulo_x);
ATF_TP_ADD_TC(tp, bpfjit_alu_neg);
ATF_TP_ADD_TC(tp, bpfjit_jmp_ja);
+ ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_invalid);
+ ATF_TP_ADD_TC(tp, bpfjit_jmp_ja_overflow);
ATF_TP_ADD_TC(tp, bpfjit_jmp_jgt_k);
ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_k);
ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_k);
@@ -3934,6 +4641,9 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, bpfjit_jmp_jge_x);
ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x);
ATF_TP_ADD_TC(tp, bpfjit_jmp_jset_x);
+ ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_ax);
+ ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_a);
+ ATF_TP_ADD_TC(tp, bpfjit_jmp_jeq_x_noinit_x);
ATF_TP_ADD_TC(tp, bpfjit_jmp_modulo_x);
ATF_TP_ADD_TC(tp, bpfjit_ld_abs);
ATF_TP_ADD_TC(tp, bpfjit_ld_abs_k_overflow);
diff --git a/contrib/netbsd-tests/net/icmp/t_forward.c b/contrib/netbsd-tests/net/icmp/t_forward.c
index d0c23cc..d418027 100644
--- a/contrib/netbsd-tests/net/icmp/t_forward.c
+++ b/contrib/netbsd-tests/net/icmp/t_forward.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_forward.c,v 1.8 2012/03/18 09:46:50 jruoho Exp $ */
+/* $NetBSD: t_forward.c,v 1.9 2015/02/26 13:03:21 martin Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: t_forward.c,v 1.8 2012/03/18 09:46:50 jruoho Exp $");
+__RCSID("$NetBSD: t_forward.c,v 1.9 2015/02/26 13:03:21 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -129,7 +129,7 @@ ATF_TC_HEAD(returndatabytes, tc)
atf_tc_set_md_var(tc, "descr", "icmp.returndatabytes with certain "
"packets can cause kernel panic (PR kern/43548)");
- atf_tc_set_md_var(tc, "timeout", "4"); /* just in case */
+ atf_tc_set_md_var(tc, "timeout", "20"); /* just in case */
}
ATF_TC_BODY(returndatabytes, tc)
diff --git a/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh b/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh
new file mode 100755
index 0000000..5dcdc9c
--- /dev/null
+++ b/contrib/netbsd-tests/net/icmp/t_icmp6_redirect.sh
@@ -0,0 +1,152 @@
+# $NetBSD: t_icmp6_redirect.sh,v 1.7 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2015 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK_LOCAL=unix://commsock1
+SOCK_PEER=unix://commsock2
+SOCK_GW1=unix://commsock3
+SOCK_GW2=unix://commsock4
+
+BUS1=bus1
+BUS2=bus2
+IP6BUS1=fc00:1::/64
+IP6BUS2=fc00:2::/64
+IP6IF0_LOCAL=fc00:1::2
+IP6IF0_PEER=fc00:2::2
+IP6IF0_GW1=fc00:1::1
+IP6IF1_GW1=fc00:2::1
+IP6IF0_GW2=fc00:1::3
+
+REDIRECT_TIMEOUT=5
+
+DEBUG=${DEBUG:-true}
+
+atf_test_case icmp6_redirect_basic cleanup
+
+icmp6_redirect_basic_head()
+{
+
+ atf_set "descr" "Test for the basically function of the ICMP6 redirect"
+ atf_set "require.progs" "rump_server rump.route rump.ping rump.ifconfig"
+}
+
+icmp6_redirect_basic_body()
+{
+ local gw1_lladdr0=
+ local gw1_lladdr1=
+ local gw2_lladdr0=
+
+ rump_server_start $SOCK_LOCAL netinet6
+ rump_server_start $SOCK_PEER netinet6
+ rump_server_start $SOCK_GW1 netinet6
+ rump_server_start $SOCK_GW2 netinet6
+
+ #
+ # Setup
+ #
+ # Setup gateway #1 (real gateway)
+ export RUMP_SERVER=${SOCK_GW1}
+ rump_server_add_iface $SOCK_GW1 shmif0 $BUS1
+ rump_server_add_iface $SOCK_GW1 shmif1 $BUS2
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_GW1}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6IF1_GW1}
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w \
+ net.inet6.ip6.forwarding=1
+ unset RUMP_SERVER
+
+ gw1_lladdr0=`get_linklocal_addr ${SOCK_GW1} shmif0`
+ gw1_lladdr1=`get_linklocal_addr ${SOCK_GW1} shmif1`
+
+ # Setup a peer behind gateway #1
+ export RUMP_SERVER=${SOCK_PEER}
+ rump_server_add_iface $SOCK_PEER shmif0 $BUS2
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_PEER}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.route add \
+ -inet6 default ${gw1_lladdr1}%shmif0
+ unset RUMP_SERVER
+
+ # Setup gateway #2 (fake gateway)
+ export RUMP_SERVER=${SOCK_GW2}
+ rump_server_add_iface $SOCK_GW2 shmif0 $BUS1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_GW2}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 -o ignore rump.route add \
+ -inet6 ${IP6BUS2} ${gw1_lladdr0}%shmif0
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w \
+ net.inet6.ip6.forwarding=1
+ unset RUMP_SERVER
+
+ gw2_lladdr0=`get_linklocal_addr ${SOCK_GW2} shmif0`
+
+ export RUMP_SERVER=${SOCK_LOCAL}
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6IF0_LOCAL}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ # Teach the fake gateway as the default gateway
+ atf_check -s exit:0 -o ignore rump.route add \
+ -inet6 default ${gw2_lladdr0}%shmif0
+ $DEBUG && rump.route get -inet6 ${IP6IF0_PEER}
+
+ atf_check -s exit:0 -o ignore rump.sysctl -w \
+ net.inet6.icmp6.redirtimeout=$REDIRECT_TIMEOUT
+
+ #
+ # Tests
+ #
+ atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n ${IP6IF0_PEER}
+ $DEBUG && rump.route show -inet6
+ # Check if a created route is correctly redirected to gateway #1
+ atf_check -s exit:0 -o match:"gateway: ${gw1_lladdr0}" rump.route get \
+ -inet6 ${IP6IF0_PEER}
+
+ atf_check -s exit:0 sleep $((REDIRECT_TIMEOUT + 2))
+ $DEBUG && rump.route show -inet6
+ # Check if the created route is expired
+ atf_check -s exit:0 -o not-match:"gateway: ${gw1_lladdr0}" rump.route get \
+ -inet6 ${IP6IF0_PEER}
+
+ rump_server_destroy_ifaces
+}
+
+icmp6_redirect_basic_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case icmp6_redirect_basic
+}
diff --git a/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh b/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh
new file mode 100755
index 0000000..6697216
--- /dev/null
+++ b/contrib/netbsd-tests/net/icmp/t_icmp_redirect.sh
@@ -0,0 +1,285 @@
+# $NetBSD: t_icmp_redirect.sh,v 1.6 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+# Most codes are derived from tests/net/route/t_flags.sh
+
+SOCK_LOCAL=unix://commsock1
+SOCK_PEER=unix://commsock2
+SOCK_GW=unix://commsock3
+BUS=bus1
+BUS2=bus2
+REDIRECT_TIMEOUT=5
+
+DEBUG=${DEBUG:-false}
+
+atf_test_case icmp_redirect_timeout cleanup
+
+icmp_redirect_timeout_head()
+{
+
+ atf_set "descr" "Tests for ICMP redirect timeout";
+ atf_set "require.progs" "rump_server";
+}
+
+setup_local()
+{
+
+ rump_server_start $SOCK_LOCAL
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.2/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 -o ignore rump.sysctl -w \
+ net.inet.icmp.redirtimeout=$REDIRECT_TIMEOUT
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+setup_peer()
+{
+
+ rump_server_start $SOCK_PEER
+ rump_server_add_iface $SOCK_PEER shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.1/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+setup_gw()
+{
+
+ rump_server_start $SOCK_GW
+ rump_server_add_iface $SOCK_GW shmif0 $BUS
+ rump_server_add_iface $SOCK_GW shmif1 $BUS2
+
+ export RUMP_SERVER=$SOCK_GW
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.254/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 10.0.2.1/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 alias 10.0.2.2/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up
+
+ # Wait until DAD completes (10 sec at most)
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif1 |grep -q tentative"
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+icmp_redirect_timeout_body()
+{
+
+ $DEBUG && ulimit -c unlimited
+
+ setup_local
+ setup_peer
+
+ ### Testing Dynamic flag ###
+
+ #
+ # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it.
+ #
+ setup_gw
+
+ #
+ # Teach the peer that 10.0.2.* is behind 10.0.0.254
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254
+ # Up, Gateway, Static
+ check_route_flags 10.0.2/24 UGS
+
+ #
+ # Setup the default gateway to the peer, 10.0.0.1
+ #
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1
+ # Up, Gateway, Static
+ check_route_flags default UGS
+
+ # Try ping 10.0.2.1
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Host, Dynamic
+ check_route_flags 10.0.2.1 UGHD
+ check_route_gw 10.0.2.1 10.0.0.254
+
+ atf_check -s exit:0 sleep $((REDIRECT_TIMEOUT + 2))
+
+ # The dynamic entry should be expired and removed
+ check_route_no_entry 10.0.2.1
+
+ export RUMP_SERVER=$SOCK_PEER
+ $DEBUG && rump.netstat -rn -f inet
+
+ rump_server_destroy_ifaces
+}
+
+icmp_redirect_timeout_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case icmp_redirect cleanup
+
+icmp_redirect_head()
+{
+
+ atf_set "descr" "Tests for icmp redirect";
+ atf_set "require.progs" "rump_server";
+}
+
+setup_redirect()
+{
+ atf_check -s exit:0 -o ignore rump.sysctl -w \
+ net.inet.ip.redirect=1
+}
+
+teardown_redirect()
+{
+ atf_check -s exit:0 -o ignore rump.sysctl -w \
+ net.inet.ip.redirect=0
+}
+
+icmp_redirect_body()
+{
+
+ $DEBUG && ulimit -c unlimited
+
+ setup_local
+ setup_peer
+
+ #
+ # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it.
+ #
+ setup_gw
+
+ #
+ # Teach the peer that 10.0.2.* is behind 10.0.0.254
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254
+ # Up, Gateway, Static
+ check_route_flags 10.0.2/24 UGS
+
+ #
+ # Setup the default gateway to the peer, 10.0.0.1
+ #
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1
+ # Up, Gateway, Static
+ check_route_flags default UGS
+
+
+ ### ICMP redirects are NOT sent by the peer ###
+
+ #
+ # Disable net.inet.ip.redirect
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ teardown_redirect
+
+ # Try ping 10.0.2.1
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # A direct route shouldn't be created
+ check_route_no_entry 10.0.2.1
+
+
+ ### ICMP redirects are sent by the peer ###
+
+ #
+ # Enable net.inet.ip.redirect
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ setup_redirect
+
+ # Try ping 10.0.2.1
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Host, Dynamic
+ check_route_flags 10.0.2.1 UGHD
+ check_route_gw 10.0.2.1 10.0.0.254
+
+ export RUMP_SERVER=$SOCK_PEER
+ $DEBUG && rump.netstat -rn -f inet
+
+
+ # cleanup
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.route delete 10.0.2.1
+ check_route_no_entry 10.0.2.1
+
+
+ ### ICMP redirects are NOT sent by the peer (again) ###
+
+ #
+ # Disable net.inet.ip.redirect
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ teardown_redirect
+
+ # Try ping 10.0.2.1
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # A direct route shouldn't be created
+ check_route_no_entry 10.0.2.1
+
+ rump_server_destroy_ifaces
+}
+
+icmp_redirect_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case icmp_redirect
+ atf_add_test_case icmp_redirect_timeout
+}
diff --git a/contrib/netbsd-tests/net/icmp/t_ping.c b/contrib/netbsd-tests/net/icmp/t_ping.c
index fd8067c..68a00c7 100644
--- a/contrib/netbsd-tests/net/icmp/t_ping.c
+++ b/contrib/netbsd-tests/net/icmp/t_ping.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $ */
+/* $NetBSD: t_ping.c,v 1.16 2015/02/26 13:06:10 martin Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: t_ping.c,v 1.15 2012/09/04 22:31:58 alnsn Exp $");
+__RCSID("$NetBSD: t_ping.c,v 1.16 2015/02/26 13:06:10 martin Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -60,7 +60,7 @@ ATF_TC_HEAD(simpleping, tc)
{
atf_tc_set_md_var(tc, "descr", "check that kernel responds to ping");
- atf_tc_set_md_var(tc, "timeout", "2");
+ atf_tc_set_md_var(tc, "timeout", "20");
}
ATF_TC_BODY(simpleping, tc)
@@ -316,7 +316,7 @@ ATF_TC_HEAD(ping_of_death, tc)
{
atf_tc_set_md_var(tc, "descr", "send a \"ping of death\"");
- atf_tc_set_md_var(tc, "timeout", "2");
+ atf_tc_set_md_var(tc, "timeout", "20");
}
ATF_TC_BODY(ping_of_death, tc)
diff --git a/contrib/netbsd-tests/net/icmp/t_ping2.sh b/contrib/netbsd-tests/net/icmp/t_ping2.sh
index 30ff73b..fc75196 100755
--- a/contrib/netbsd-tests/net/icmp/t_ping2.sh
+++ b/contrib/netbsd-tests/net/icmp/t_ping2.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_ping2.sh,v 1.4 2010/12/30 16:58:07 pooka Exp $
+# $NetBSD: t_ping2.sh,v 1.5 2016/08/10 22:17:44 kre Exp $
#
# Copyright (c) 2010 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -26,7 +26,7 @@
#
netserver=\
-"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif"
+"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev"
atf_test_case basic cleanup
basic_head()
diff --git a/contrib/netbsd-tests/net/if/ifconf.c b/contrib/netbsd-tests/net/if/ifconf.c
new file mode 100644
index 0000000..424c5e8
--- /dev/null
+++ b/contrib/netbsd-tests/net/if/ifconf.c
@@ -0,0 +1,134 @@
+/* $NetBSD: ifconf.c,v 1.1 2014/12/08 04:23:03 ozaki-r Exp $ */
+/*
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * 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.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: ifconf.c,v 1.1 2014/12/08 04:23:03 ozaki-r Exp $");
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <stdio.h>
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+static void
+help(void)
+{
+ fprintf(stderr, "usage:\n\t%s total\n\t%s list [<nifreqs>]\n",
+ getprogname(), getprogname());
+ exit(EXIT_FAILURE);
+}
+
+static int
+get_number_of_entries(void)
+{
+ int fd, r;
+ struct ifconf ifc;
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1)
+ err(EXIT_FAILURE, "socket");
+
+ ifc.ifc_len = 0;
+ ifc.ifc_buf = NULL;
+
+ r = ioctl(fd, SIOCGIFCONF, &ifc);
+ if (r == -1)
+ err(EXIT_FAILURE, "ioctl");
+
+ close(fd);
+
+ return ifc.ifc_len / sizeof(struct ifreq);
+}
+
+static void
+show_number_of_entries(void)
+{
+ printf("%d\n", get_number_of_entries());
+}
+
+static void
+show_interfaces(int nifreqs)
+{
+ int i, fd, r;
+ struct ifconf ifc;
+ struct ifreq *ifreqs;
+
+ if (nifreqs == 0)
+ nifreqs = get_number_of_entries();
+
+ if (nifreqs <= 0)
+ errx(EXIT_FAILURE, "nifreqs=%d", nifreqs);
+
+ ifreqs = malloc(sizeof(struct ifreq) * nifreqs);
+ if (ifreqs == NULL)
+ err(EXIT_FAILURE, "malloc(sizeof(ifreq) * %d)", nifreqs);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1)
+ err(EXIT_FAILURE, "socket");
+
+ ifc.ifc_len = sizeof(struct ifreq) * nifreqs;
+ ifc.ifc_req = ifreqs;
+
+ r = ioctl(fd, SIOCGIFCONF, &ifc);
+ if (r == -1)
+ err(EXIT_FAILURE, "ioctl");
+ close(fd);
+
+ for (i=0; i < (int)(ifc.ifc_len / sizeof(struct ifreq)); i++) {
+ printf("%s: af=%hhu socklen=%hhu\n", ifreqs[i].ifr_name,
+ ifreqs[i].ifr_addr.sa_family, ifreqs[i].ifr_addr.sa_len);
+ }
+
+ free(ifreqs);
+}
+
+int
+main(int argc, char *argv[])
+{
+ if (argc < 2)
+ help();
+
+ if (strcmp(argv[1], "total") == 0) {
+ show_number_of_entries();
+ } else if (strcmp(argv[1], "list") == 0) {
+ if (argc == 2)
+ show_interfaces(0);
+ else if (argc == 3)
+ show_interfaces(atoi(argv[2]));
+ else
+ help();
+ } else
+ help();
+
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/netbsd-tests/net/if/t_compat.c b/contrib/netbsd-tests/net/if/t_compat.c
index 4798034..9eb84a3 100644
--- a/contrib/netbsd-tests/net/if/t_compat.c
+++ b/contrib/netbsd-tests/net/if/t_compat.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_compat.c,v 1.1 2010/11/07 19:53:42 pooka Exp $ */
+/* $NetBSD: t_compat.c,v 1.4 2016/11/12 15:12:59 kre Exp $ */
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -65,6 +65,8 @@ ATF_TC_BODY(OOSIOCGIFBRDADDR, tc)
sprintf(ifreq.ifr_name, "shmif%d", ifnum);
netcfg_rump_if(ifreq.ifr_name, "1.7.64.10", "255.255.0.0");
+ atf_tc_expect_fail("PR kern/51610: rump does not include COMPAT_43");
+
/* query kernel for iface bcast */
RL(fd = rump_sys_socket(AF_INET, SOCK_DGRAM, 0));
RL(rump_sys_ioctl(fd, OOSIOCGIFBRDADDR, &ifreq));
diff --git a/contrib/netbsd-tests/net/if/t_ifconf.sh b/contrib/netbsd-tests/net/if/t_ifconf.sh
new file mode 100755
index 0000000..f56e9e3
--- /dev/null
+++ b/contrib/netbsd-tests/net/if/t_ifconf.sh
@@ -0,0 +1,100 @@
+# $NetBSD: t_ifconf.sh,v 1.3 2016/08/10 22:30:02 kre Exp $
+#
+# Copyright (c) 2014 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+RUMP_SERVER1=unix://./r1
+
+RUMP_FLAGS=\
+"-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpdev"
+
+atf_test_case basic cleanup
+basic_head()
+{
+
+ atf_set "descr" "basic ifconf (SIOCGIFCONF) test"
+ atf_set "require.progs" "rump_server"
+}
+
+basic_body()
+{
+ local ifconf="$(atf_get_srcdir)/ifconf"
+
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1}
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+
+ # lo0 (127.0.0.1 and link local)
+ atf_check -s exit:0 -o match:'^2$' "$ifconf" total
+ atf_check -s exit:0 -o match:'lo0' "$ifconf" list
+
+ # Add shmif0 (no address)
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 -o match:'^3$' "$ifconf" total
+ atf_check -s exit:0 -o match:'shmif0' "$ifconf" list
+
+ # Add shmif1 (no address)
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 -o match:'^4$' "$ifconf" total
+ atf_check -s exit:0 -o match:'shmif1' "$ifconf" list
+
+ # Add an address to shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24
+ atf_check -s exit:0 -o match:'^5$' "$ifconf" total
+
+ # Vary the number of requesting interfaces
+ atf_check -s exit:0 -o match:1 -x "$ifconf list 1 | wc -l"
+ atf_check -s exit:0 -o match:2 -x "$ifconf list 2 | wc -l"
+ atf_check -s exit:0 -o match:3 -x "$ifconf list 3 | wc -l"
+ atf_check -s exit:0 -o match:4 -x "$ifconf list 4 | wc -l"
+ atf_check -s exit:0 -o match:5 -x "$ifconf list 5 | wc -l"
+ atf_check -s exit:0 -o match:5 -x "$ifconf list 6 | wc -l"
+
+ # Check if removing an interface is reflected
+ atf_check -s exit:0 rump.ifconfig shmif0 destroy
+ atf_check -s exit:0 -o match:'^3$' "$ifconf" total
+ atf_check -s exit:0 -o not-match:'shmif0' "$ifconf" list
+ atf_check -s exit:0 -o match:1 -x "$ifconf list 1 | wc -l"
+ atf_check -s exit:0 -o match:2 -x "$ifconf list 2 | wc -l"
+ atf_check -s exit:0 -o match:3 -x "$ifconf list 3 | wc -l"
+ atf_check -s exit:0 -o match:3 -x "$ifconf list 4 | wc -l"
+
+ unset LD_PRELOAD
+ unset RUMP_SERVER
+}
+
+basic_cleanup()
+{
+
+ RUMP_SERVER=${RUMP_SERVER1} rump.halt
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case basic
+}
diff --git a/contrib/netbsd-tests/net/if/t_ifconfig.sh b/contrib/netbsd-tests/net/if/t_ifconfig.sh
new file mode 100755
index 0000000..a610017
--- /dev/null
+++ b/contrib/netbsd-tests/net/if/t_ifconfig.sh
@@ -0,0 +1,333 @@
+# $NetBSD: t_ifconfig.sh,v 1.14 2016/10/01 22:15:04 kre Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+RUMP_SERVER1=unix://./r1
+RUMP_SERVER2=unix://./r2
+
+RUMP_FLAGS=\
+"-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 -lrumpnet_shmif"
+RUMP_FLAGS="${RUMP_FLAGS} -lrumpdev"
+
+TIMEOUT=3
+
+anycast="[Aa][Nn][Yy][Cc][Aa][Ss][Tt]"
+deprecated="[Dd][Ee][Pp][Rr][Ee][Cc][Aa][Tt][Ee][Dd]"
+
+atf_test_case ifconfig_create_destroy cleanup
+ifconfig_create_destroy_head()
+{
+
+ atf_set "descr" "tests of ifconfig create and destroy"
+ atf_set "require.progs" "rump_server"
+}
+
+ifconfig_create_destroy_body()
+{
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1}
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+
+ # Create and destroy (no address)
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 destroy
+
+ # Create and destroy (with an IPv4 address)
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif0 destroy
+
+ # Create and destroy (with an IPv6 address)
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif0 destroy
+
+ unset RUMP_SERVER
+}
+
+ifconfig_create_destroy_cleanup()
+{
+
+ RUMP_SERVER=${RUMP_SERVER1} rump.halt
+}
+
+atf_test_case ifconfig_options cleanup
+ifconfig_options_head()
+{
+
+ atf_set "descr" "tests of ifconfig options"
+ atf_set "require.progs" "rump_server"
+}
+
+ifconfig_options_body()
+{
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 rump_server $RUMP_FLAGS $RUMP_SERVER1
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 create
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 linkstr bus1
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet 10.0.0.1/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 fc00::1/64
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ $DEBUG && rump.ifconfig shmif0
+
+ # ifconfig [-N] interface address_family
+ # -N resolves hostnames
+ atf_check -s exit:0 -o match:'inet 127.0.0.1' rump.ifconfig lo0 inet
+ atf_check -s exit:0 -o match:'inet localhost' rump.ifconfig -N lo0 inet
+ atf_check -s exit:0 -o match:'inet6 ::1' rump.ifconfig lo0 inet6
+ atf_check -s exit:0 -o match:'inet6 localhost' rump.ifconfig -N lo0 inet6
+ atf_check -s not-exit:0 -e match:'not supported' rump.ifconfig lo0 atalk
+ atf_check -s not-exit:0 -e match:'not supported' rump.ifconfig -N lo0 atalk
+ atf_check -s exit:0 -o ignore rump.ifconfig lo0 link
+ atf_check -s exit:0 -o ignore rump.ifconfig -N lo0 link
+
+ # ifconfig [-hLmNvz] interface
+ # -h -v shows statistics in human readable format
+ atf_check -s exit:0 -o ignore rump.ifconfig -h -v lo0
+ # -L shows IPv6 lifetime
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 fc00::2 \
+ pltime 100
+ $DEBUG && rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0
+ # -m shows all of the supported media (not supported in shmif)
+ $DEBUG && rump.ifconfig -m shmif0
+ atf_check -s exit:0 -o ignore rump.ifconfig -m shmif0
+ atf_check -s exit:0 -o match:'localhost' rump.ifconfig -N lo0
+ atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -v lo0
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT localhost
+ # -z clears and shows statistics at that point
+ atf_check -s exit:0 -o match:'2 packets' rump.ifconfig -z lo0
+ atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -v lo0
+
+ # ifconfig -a [-bdhLNmsuvz]
+ # -a shows all interfaces in the system
+ $DEBUG && rump.ifconfig -a
+ atf_check -s exit:0 -o match:'shmif0' -o match:'lo0' rump.ifconfig -a
+ # -a -b shows only broadcast interfaces
+ atf_check -s exit:0 -o match:'shmif0' -o not-match:'lo0' rump.ifconfig -a -b
+ # -a -d shows only down interfaces
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -a -d
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o not-match:'shmif0' rump.ifconfig -a -d
+ atf_check -s exit:0 -o match:'pltime' rump.ifconfig -a -L
+ atf_check -s exit:0 -o match:'vltime' rump.ifconfig -a -L
+ atf_check -s exit:0 -o match:'localhost' rump.ifconfig -a -N
+ atf_check -s exit:0 -o ignore rump.ifconfig -a -m
+ # -a -s shows only interfaces connected to a network
+ # (shmif is always connected)
+ $DEBUG && rump.ifconfig -a -s
+ atf_check -s exit:0 -o ignore rump.ifconfig -a -s
+ # -a -u shows only up interfaces
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -a -u
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down
+ atf_check -s exit:0 -o not-match:'shmif0' rump.ifconfig -a -u
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -a -v
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT localhost
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 down
+ atf_check -s exit:0 -o match:'2 packets' rump.ifconfig -a -z
+ atf_check -s exit:0 -o not-match:'2 packets' rump.ifconfig -a -v
+ atf_check -s exit:0 -o match:'0 packets' rump.ifconfig -a -v
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+
+ # ifconfig -l [-bdsu]
+ # -l shows only inteface names
+ atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -b
+ atf_check -s exit:0 -o not-match:'lo0' rump.ifconfig -l -b
+ atf_check -s exit:0 -o ignore rump.ifconfig -l -d
+ atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l -s
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -s
+ atf_check -s exit:0 -o match:'lo0' rump.ifconfig -l -u
+ atf_check -s exit:0 -o match:'shmif0' rump.ifconfig -l -u
+
+ # ifconfig -s interface
+ # -s interface exists with 0 / 1 if connected / disconnected
+ atf_check -s exit:0 -o empty rump.ifconfig -s lo0
+ atf_check -s exit:0 -o empty rump.ifconfig -s shmif0
+
+ # ifconfig -C
+ # -C shows all of the interface cloners available on the system
+ atf_check -s exit:0 -o match:'shmif lo carp' rump.ifconfig -C
+
+ unset RUMP_SERVER
+}
+
+ifconfig_options_cleanup()
+{
+
+ env RUMP_SERVER=${RUMP_SERVER1} rump.halt
+}
+
+
+atf_test_case ifconfig_parameters cleanup
+ifconfig_parameters_head()
+{
+ atf_set "descr" "tests of interface parameters"
+ atf_set "require.progs" "rump_server"
+}
+
+ifconfig_parameters_body()
+{
+ local interval=
+
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER1}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS} ${RUMP_SERVER2}
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${RUMP_SERVER2}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.2/24
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.3/24 alias
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+
+ # active
+ atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:01 active
+ atf_check -s exit:0 -o match:'address:.b2:a0:75:00:00:01' \
+ rump.ifconfig shmif0
+ # down, up
+ atf_check -s exit:0 rump.ifconfig shmif0 down
+ atf_check -s not-exit:0 -o ignore -e ignore rump.ping -c 1 \
+ -w $TIMEOUT -n 192.168.0.2
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT -n 192.168.0.2
+
+ # alias
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1/24 alias
+ atf_check -s exit:0 -o match:'192.168.1.1/24' rump.ifconfig shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1/24 -alias
+ atf_check -s exit:0 -o not-match:'192.168.1.1/24' rump.ifconfig shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2
+ atf_check -s exit:0 -o match:'fc00::1' rump.ifconfig shmif0 inet6
+ atf_check -s exit:0 -o match:'fc00::2' rump.ifconfig shmif0 inet6
+
+ # delete
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1 alias
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.1.1 delete
+ atf_check -s exit:0 -o not-match:'192.168.1.1' rump.ifconfig shmif0 inet
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.1 delete
+ atf_check -s exit:0 -o not-match:'192.168.0.1' rump.ifconfig shmif0 inet
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 delete
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2 delete
+ atf_check -s exit:0 -o not-match:'fc00::1' rump.ifconfig shmif0 inet6
+ atf_check -s exit:0 -o not-match:'fc00::2' rump.ifconfig shmif0 inet6
+ # can delete inactive link
+ atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:02
+ atf_check -s exit:0 rump.ifconfig shmif0 link b2:a0:75:00:00:02 delete
+ # cannot delete active link
+ atf_check -s not-exit:0 -e match:'SIOCDLIFADDR: Device busy' \
+ rump.ifconfig shmif0 link b2:a0:75:00:00:01 delete
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 192.168.0.1/24
+
+ # arp
+ atf_check -s exit:0 rump.ifconfig shmif0 -arp
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -c 1 -w $TIMEOUT -n 192.168.0.3
+ atf_check -s exit:0 -o not-match:'192.168.0.3' rump.arp -an
+ # The entry shouldn't appear in the routing table anymore
+ atf_check -s exit:0 -o not-match:'192.168.0.3' rump.netstat -nr
+
+ # netmask
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 netmask 255.255.255.0 alias
+ atf_check -s exit:0 -o match:'172.16.0/24' rump.netstat -rn -f inet
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 delete
+
+ # broadcast (does it not work?)
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 172.16.0.1 \
+ broadcast 255.255.255.255 alias
+ atf_check -s exit:0 -o match:'broadcast 255.255.255.255' \
+ rump.ifconfig shmif0 inet
+
+ # metric (external only)
+ atf_check -s exit:0 rump.ifconfig shmif0 metric 10
+ atf_check -s exit:0 rump.ifconfig shmif0 metric 0
+
+ # prefixlen
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::1 prefixlen 70
+ atf_check -s exit:0 -o match:'fc00::/70' rump.netstat -rn -f inet6
+
+ # anycast
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2 anycast
+ atf_check -s exit:0 -o match:"fc00::2.+$anycast" rump.ifconfig shmif0 inet6
+
+ # deprecated
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 deprecated
+ # Not deprecated immediately. Need to wait nd6_timer that does it is scheduled.
+ interval=$(sysctl -n net.inet6.icmp6.nd6_prune)
+ atf_check -s exit:0 sleep $((interval + 1))
+ atf_check -s exit:0 -o match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 -deprecated
+ atf_check -s exit:0 -o not-match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6
+
+ # pltime
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::3 pltime 3
+ atf_check -s exit:0 -o not-match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6
+ atf_check -s exit:0 sleep 5
+ atf_check -s exit:0 -o match:"fc00::3.+$deprecated" rump.ifconfig shmif0 inet6
+
+ # eui64
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00:1::0 eui64
+ atf_check -s exit:0 -o match:'fc00:1::' rump.ifconfig shmif0 inet6
+
+ unset RUMP_SERVER
+}
+
+ifconfig_parameters_cleanup()
+{
+ env RUMP_SERVER=${RUMP_SERVER1} rump.halt
+ env RUMP_SERVER=${RUMP_SERVER2} rump.halt
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case ifconfig_create_destroy
+ atf_add_test_case ifconfig_options
+ atf_add_test_case ifconfig_parameters
+}
diff --git a/contrib/netbsd-tests/net/if_bridge/t_bridge.sh b/contrib/netbsd-tests/net/if_bridge/t_bridge.sh
index 5fbafc7..25edb35 100755
--- a/contrib/netbsd-tests/net/if_bridge/t_bridge.sh
+++ b/contrib/netbsd-tests/net/if_bridge/t_bridge.sh
@@ -1,5 +1,4 @@
-#! /usr/bin/atf-sh
-# $NetBSD: t_bridge.sh,v 1.1 2014/09/18 15:13:27 ozaki-r Exp $
+# $NetBSD: t_bridge.sh,v 1.16 2016/11/25 08:51:16 ozaki-r Exp $
#
# Copyright (c) 2014 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -26,9 +25,6 @@
# POSSIBILITY OF SUCH DAMAGE.
#
-inetserver="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_bridge -lrumpnet_shmif"
-inet6server="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 -lrumpnet_bridge -lrumpnet_shmif"
-
SOCK1=unix://commsock1
SOCK2=unix://commsock2
SOCK3=unix://commsock3
@@ -36,22 +32,50 @@ IP1=10.0.0.1
IP2=10.0.0.2
IP61=fc00::1
IP62=fc00::2
+IPBR1=10.0.0.11
+IPBR2=10.0.0.12
+IP6BR1=fc00::11
+IP6BR2=fc00::12
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=5
-atf_test_case basic cleanup
-atf_test_case basic6 cleanup
+atf_test_case bridge_ipv4 cleanup
+atf_test_case bridge_ipv6 cleanup
+atf_test_case bridge_rtable cleanup
+atf_test_case bridge_member_ipv4 cleanup
+atf_test_case bridge_member_ipv6 cleanup
-basic_head()
+bridge_ipv4_head()
{
atf_set "descr" "Does simple if_bridge tests"
atf_set "require.progs" "rump_server"
}
-basic6_head()
+bridge_ipv6_head()
{
atf_set "descr" "Does simple if_bridge tests (IPv6)"
atf_set "require.progs" "rump_server"
}
+bridge_rtable_head()
+{
+ atf_set "descr" "Tests route table operations of if_bridge"
+ atf_set "require.progs" "rump_server"
+}
+
+bridge_member_ipv4_head()
+{
+ atf_set "descr" "Tests if_bridge with members with an IP address"
+ atf_set "require.progs" "rump_server"
+}
+
+bridge_member_ipv6_head()
+{
+ atf_set "descr" "Tests if_bridge with members with an IP address (IPv6)"
+ atf_set "require.progs" "rump_server"
+}
+
setup_endpoint()
{
sock=${1}
@@ -59,9 +83,8 @@ setup_endpoint()
bus=${3}
mode=${4}
+ rump_server_add_iface $sock shmif0 $bus
export RUMP_SERVER=${sock}
- atf_check -s exit:0 rump.ifconfig shmif0 create
- atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${bus}
if [ $mode = "ipv6" ]; then
atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr}
else
@@ -69,7 +92,7 @@ setup_endpoint()
fi
atf_check -s exit:0 rump.ifconfig shmif0 up
- rump.ifconfig shmif0
+ $DEBUG && rump.ifconfig shmif0
}
test_endpoint()
@@ -82,22 +105,12 @@ test_endpoint()
export RUMP_SERVER=${sock}
atf_check -s exit:0 -o match:shmif0 rump.ifconfig
if [ $mode = "ipv6" ]; then
- export LD_PRELOAD=/usr/lib/librumphijack.so
- atf_check -s exit:0 -o ignore ping6 -n -c 1 ${addr}
- unset LD_PRELOAD
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr}
else
- atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 ${addr}
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr}
fi
}
-show_endpoint()
-{
- sock=${1}
-
- export RUMP_SERVER=${sock}
- rump.ifconfig -v shmif0
-}
-
test_setup()
{
test_endpoint $SOCK1 $IP1 bus1 ipv4
@@ -120,21 +133,20 @@ test_setup6()
setup_bridge_server()
{
+
+ rump_server_add_iface $SOCK2 shmif0 bus1
+ rump_server_add_iface $SOCK2 shmif1 bus2
export RUMP_SERVER=$SOCK2
- atf_check -s exit:0 rump.ifconfig shmif0 create
- atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus1
atf_check -s exit:0 rump.ifconfig shmif0 up
-
- atf_check -s exit:0 rump.ifconfig shmif1 create
- atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus2
atf_check -s exit:0 rump.ifconfig shmif1 up
}
setup()
{
- atf_check -s exit:0 ${inetserver} $SOCK1
- atf_check -s exit:0 ${inetserver} $SOCK2
- atf_check -s exit:0 ${inetserver} $SOCK3
+
+ rump_server_start $SOCK1 bridge
+ rump_server_start $SOCK2 bridge
+ rump_server_start $SOCK3 bridge
setup_endpoint $SOCK1 $IP1 bus1 ipv4
setup_endpoint $SOCK3 $IP2 bus2 ipv4
@@ -143,9 +155,10 @@ setup()
setup6()
{
- atf_check -s exit:0 ${inet6server} $SOCK1
- atf_check -s exit:0 ${inet6server} $SOCK2
- atf_check -s exit:0 ${inet6server} $SOCK3
+
+ rump_server_start $SOCK1 netinet6 bridge
+ rump_server_start $SOCK2 netinet6 bridge
+ rump_server_start $SOCK3 netinet6 bridge
setup_endpoint $SOCK1 $IP61 bus1 ipv6
setup_endpoint $SOCK3 $IP62 bus2 ipv6
@@ -167,6 +180,32 @@ setup_bridge()
rump.ifconfig shmif1
}
+setup_member_ip()
+{
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ atf_check -s exit:0 rump.ifconfig shmif0 $IPBR1/24
+ atf_check -s exit:0 rump.ifconfig shmif1 $IPBR2/24
+ atf_check -s exit:0 rump.ifconfig -w 10
+ /sbin/brconfig bridge0
+ unset LD_PRELOAD
+ rump.ifconfig shmif0
+ rump.ifconfig shmif1
+}
+
+setup_member_ip6()
+{
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6BR1
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6BR2
+ atf_check -s exit:0 rump.ifconfig -w 10
+ /sbin/brconfig bridge0
+ unset LD_PRELOAD
+ rump.ifconfig shmif0
+ rump.ifconfig shmif1
+}
+
teardown_bridge()
{
export RUMP_SERVER=$SOCK2
@@ -190,19 +229,6 @@ test_setup_bridge()
unset LD_PRELOAD
}
-cleanup()
-{
- env RUMP_SERVER=$SOCK1 rump.halt
- env RUMP_SERVER=$SOCK2 rump.halt
- env RUMP_SERVER=$SOCK3 rump.halt
-}
-
-dump_bus()
-{
- /usr/bin/shmif_dumpbus -p - bus1 2>/dev/null| /usr/sbin/tcpdump -n -e -r -
- /usr/bin/shmif_dumpbus -p - bus2 2>/dev/null| /usr/sbin/tcpdump -n -e -r -
-}
-
down_up_interfaces()
{
export RUMP_SERVER=$SOCK1
@@ -216,97 +242,332 @@ down_up_interfaces()
test_ping_failure()
{
export RUMP_SERVER=$SOCK1
- atf_check -s not-exit:0 -o ignore rump.ping -q -n -w 1 -c 1 $IP2
+ atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2
export RUMP_SERVER=$SOCK3
- atf_check -s not-exit:0 -o ignore rump.ping -q -n -w 1 -c 1 $IP1
+ atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1
}
test_ping_success()
{
export RUMP_SERVER=$SOCK1
rump.ifconfig -v shmif0
- atf_check -s exit:0 -o ignore rump.ping -q -n -w 1 -c 1 $IP2
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2
rump.ifconfig -v shmif0
export RUMP_SERVER=$SOCK3
rump.ifconfig -v shmif0
- atf_check -s exit:0 -o ignore rump.ping -q -n -w 1 -c 1 $IP1
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1
rump.ifconfig -v shmif0
}
test_ping6_failure()
{
- export LD_PRELOAD=/usr/lib/librumphijack.so
export RUMP_SERVER=$SOCK1
- atf_check -s not-exit:0 -o ignore ping6 -q -n -c 1 $IP62
+ atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62
export RUMP_SERVER=$SOCK3
- atf_check -s not-exit:0 -o ignore ping6 -q -n -c 1 $IP61
- unset LD_PRELOAD
+ atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61
}
test_ping6_success()
{
export RUMP_SERVER=$SOCK1
rump.ifconfig -v shmif0
- export LD_PRELOAD=/usr/lib/librumphijack.so
- atf_check -s exit:0 -o ignore ping6 -q -n -c 1 $IP62
- unset LD_PRELOAD
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62
+ rump.ifconfig -v shmif0
+
+ export RUMP_SERVER=$SOCK3
+ rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61
+ rump.ifconfig -v shmif0
+}
+
+test_ping_member()
+{
+ export RUMP_SERVER=$SOCK1
+ rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1
+ rump.ifconfig -v shmif0
+ # Test for PR#48104
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2
+ rump.ifconfig -v shmif0
+
+ export RUMP_SERVER=$SOCK3
+ rump.ifconfig -v shmif0
+ # Test for PR#48104
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1
+ rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2
+ rump.ifconfig -v shmif0
+}
+
+test_ping6_member()
+{
+ export RUMP_SERVER=$SOCK1
+ rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1
+ rump.ifconfig -v shmif0
+ # Test for PR#48104
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2
rump.ifconfig -v shmif0
export RUMP_SERVER=$SOCK3
rump.ifconfig -v shmif0
+ # Test for PR#48104
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1
+ rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2
+ rump.ifconfig -v shmif0
+}
+
+get_number_of_caches()
+{
+ export RUMP_SERVER=$SOCK2
export LD_PRELOAD=/usr/lib/librumphijack.so
- atf_check -s exit:0 -o ignore ping6 -q -n -c 1 $IP61
+ echo $(($(/sbin/brconfig bridge0 |grep -A 100 "Address cache" |wc -l) - 1))
+ unset LD_PRELOAD
+}
+
+test_brconfig_maxaddr()
+{
+ addr1= addr3= n=
+
+ # Get MAC addresses of the endpoints.
+ addr1=$(get_macaddr $SOCK1 shmif0)
+ addr3=$(get_macaddr $SOCK3 shmif0)
+
+ # Refill the MAC addresses of the endpoints.
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0
+
+ # Check the default # of caches is 100
+ atf_check -s exit:0 -o match:"max cache: 100" /sbin/brconfig bridge0
+
+ # Test two MAC addresses are cached
+ n=$(get_number_of_caches)
+ atf_check_equal $n 2
+
+ # Limit # of caches to one
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 maxaddr 1
+ atf_check -s exit:0 -o match:"max cache: 1" /sbin/brconfig bridge0
+ /sbin/brconfig bridge0
+
+ # Test just one address is cached
+ n=$(get_number_of_caches)
+ atf_check_equal $n 1
+
+ # Increase # of caches to two
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 maxaddr 2
+ atf_check -s exit:0 -o match:"max cache: 2" /sbin/brconfig bridge0
+ unset LD_PRELOAD
+
+ # Test we can cache two addresses again
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0
unset LD_PRELOAD
- rump.ifconfig -v shmif0
}
-basic_body()
+bridge_ipv4_body()
{
setup
test_setup
+ # Enable once PR kern/49219 is fixed
+ #test_ping_failure
+
setup_bridge
+ sleep 1
test_setup_bridge
-
test_ping_success
teardown_bridge
test_ping_failure
+
+ rump_server_destroy_ifaces
}
-basic6_body()
+bridge_ipv6_body()
{
setup6
test_setup6
- # TODO: enable once ping6 implements timeout feature
- #test_ping6_failure
+ test_ping6_failure
+
+ setup_bridge
+ sleep 1
+ test_setup_bridge
+ test_ping6_success
+
+ teardown_bridge
+ test_ping6_failure
+
+ rump_server_destroy_ifaces
+}
+
+bridge_rtable_body()
+{
+ addr1= addr3=
+
+ setup
+ setup_bridge
+
+ # Get MAC addresses of the endpoints.
+ addr1=$(get_macaddr $SOCK1 shmif0)
+ addr3=$(get_macaddr $SOCK3 shmif0)
+
+ # Confirm there is no MAC address caches.
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ $DEBUG && /sbin/brconfig bridge0
+ atf_check -s exit:0 -o not-match:"$addr1" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o not-match:"$addr3" /sbin/brconfig bridge0
+ unset LD_PRELOAD
+
+ # Make the bridge learn the MAC addresses of the endpoints.
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2
+ unset RUMP_SERVER
+
+ # Tests the addresses are in the cache.
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ $DEBUG && /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0
+
+ # Tests brconfig deladdr
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 deladdr "$addr1"
+ atf_check -s exit:0 -o not-match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 deladdr "$addr3"
+ atf_check -s exit:0 -o not-match:"$addr3 shmif1" /sbin/brconfig bridge0
+ unset LD_PRELOAD
+
+ # Refill the MAC addresses of the endpoints.
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP2
+ unset RUMP_SERVER
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ $DEBUG && /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o match:"$addr3 shmif1" /sbin/brconfig bridge0
+
+ # Tests brconfig flush.
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 flush
+ atf_check -s exit:0 -o not-match:"$addr1 shmif0" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o not-match:"$addr3 shmif1" /sbin/brconfig bridge0
+ unset LD_PRELOAD
+
+ # Tests brconfig timeout.
+ export RUMP_SERVER=$SOCK2
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ atf_check -s exit:0 -o match:"timeout: 1200" /sbin/brconfig bridge0
+ atf_check -s exit:0 -o ignore /sbin/brconfig bridge0 timeout 10
+ atf_check -s exit:0 -o match:"timeout: 10" /sbin/brconfig bridge0
+ unset LD_PRELOAD
+
+ # Tests brconfig maxaddr.
+ test_brconfig_maxaddr
+
+ # TODO: brconfig static/flushall/discover/learn
+ # TODO: cache expiration; it takes 5 minutes at least and we want to
+ # wait here so long. Should we have a sysctl to change the period?
+
+ rump_server_destroy_ifaces
+}
+
+bridge_member_ipv4_body()
+{
+ setup
+ test_setup
+
+ # Enable once PR kern/49219 is fixed
+ #test_ping_failure
setup_bridge
+ sleep 1
test_setup_bridge
+ test_ping_success
+
+ setup_member_ip
+ test_ping_member
+
+ teardown_bridge
+ test_ping_failure
+
+ rump_server_destroy_ifaces
+}
+
+bridge_member_ipv6_body()
+{
+ setup6
+ test_setup6
+
+ test_ping6_failure
+ setup_bridge
+ sleep 1
+ test_setup_bridge
test_ping6_success
+ setup_member_ip6
+ test_ping6_member
+
teardown_bridge
- # TODO: enable once ping6 implements timeout feature
- #test_ping6_failure
+ test_ping6_failure
+
+ rump_server_destroy_ifaces
}
-basic_cleanup()
+bridge_ipv4_cleanup()
{
- dump_bus
+
+ $DEBUG && dump
+ cleanup
+}
+
+bridge_ipv6_cleanup()
+{
+
+ $DEBUG && dump
cleanup
}
-basic6_cleanup()
+bridge_rtable_cleanup()
{
- dump_bus
+
+ $DEBUG && dump
+ cleanup
+}
+
+bridge_member_ipv4_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+bridge_member_ipv6_cleanup()
+{
+
+ $DEBUG && dump
cleanup
}
atf_init_test_cases()
{
- atf_add_test_case basic
- atf_add_test_case basic6
+ atf_add_test_case bridge_ipv4
+ atf_add_test_case bridge_ipv6
+ atf_add_test_case bridge_rtable
+ atf_add_test_case bridge_member_ipv4
+ atf_add_test_case bridge_member_ipv6
}
diff --git a/contrib/netbsd-tests/net/if_gif/t_gif.sh b/contrib/netbsd-tests/net/if_gif/t_gif.sh
new file mode 100755
index 0000000..8690d78
--- /dev/null
+++ b/contrib/netbsd-tests/net/if_gif/t_gif.sh
@@ -0,0 +1,763 @@
+# $NetBSD: t_gif.sh,v 1.9 2016/12/21 09:46:39 ozaki-r Exp $
+#
+# Copyright (c) 2015 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK1=unix://commsock1 # for ROUTER1
+SOCK2=unix://commsock2 # for ROUTER2
+ROUTER1_LANIP=192.168.1.1
+ROUTER1_LANNET=192.168.1.0/24
+ROUTER1_WANIP=10.0.0.1
+ROUTER1_GIFIP=172.16.1.1
+ROUTER1_WANIP_DUMMY=10.0.0.11
+ROUTER1_GIFIP_DUMMY=172.16.11.1
+ROUTER1_GIFIP_RECURSIVE1=172.16.101.1
+ROUTER1_GIFIP_RECURSIVE2=172.16.201.1
+ROUTER2_LANIP=192.168.2.1
+ROUTER2_LANNET=192.168.2.0/24
+ROUTER2_WANIP=10.0.0.2
+ROUTER2_GIFIP=172.16.2.1
+ROUTER2_WANIP_DUMMY=10.0.0.12
+ROUTER2_GIFIP_DUMMY=172.16.12.1
+ROUTER2_GIFIP_RECURSIVE1=172.16.102.1
+ROUTER2_GIFIP_RECURSIVE2=172.16.202.1
+
+ROUTER1_LANIP6=fc00:1::1
+ROUTER1_LANNET6=fc00:1::/64
+ROUTER1_WANIP6=fc00::1
+ROUTER1_GIFIP6=fc00:3::1
+ROUTER1_WANIP6_DUMMY=fc00::11
+ROUTER1_GIFIP6_DUMMY=fc00:13::1
+ROUTER1_GIFIP6_RECURSIVE1=fc00:103::1
+ROUTER1_GIFIP6_RECURSIVE2=fc00:203::1
+ROUTER2_LANIP6=fc00:2::1
+ROUTER2_LANNET6=fc00:2::/64
+ROUTER2_WANIP6=fc00::2
+ROUTER2_GIFIP6=fc00:4::1
+ROUTER2_WANIP6_DUMMY=fc00::12
+ROUTER2_GIFIP6_DUMMY=fc00:14::1
+ROUTER2_GIFIP6_RECURSIVE1=fc00:104::1
+ROUTER2_GIFIP6_RECURSIVE2=fc00:204::1
+
+DEBUG=${DEBUG:-true}
+TIMEOUT=5
+
+setup_router()
+{
+ sock=${1}
+ lan=${2}
+ lan_mode=${3}
+ wan=${4}
+ wan_mode=${5}
+
+ rump_server_add_iface $sock shmif0 bus0
+ rump_server_add_iface $sock shmif1 bus1
+
+ export RUMP_SERVER=${sock}
+ if [ ${lan_mode} = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${lan}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif0 inet ${lan} netmask 0xffffff00
+ fi
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ rump.ifconfig shmif0
+
+ if [ ${wan_mode} = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${wan}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif1 inet ${wan} netmask 0xff000000
+ fi
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ rump.ifconfig shmif1
+}
+
+test_router()
+{
+ sock=${1}
+ lan=${2}
+ lan_mode=${3}
+ wan=${4}
+ wan_mode=${5}
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 -o match:shmif0 rump.ifconfig
+ if [ ${lan_mode} = "ipv6" ]; then
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${lan}
+ else
+ atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${lan}
+ fi
+
+ atf_check -s exit:0 -o match:shmif1 rump.ifconfig
+ if [ ${wan_mode} = "ipv6" ]; then
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${wan}
+ else
+ atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${wan}
+ fi
+}
+
+setup()
+{
+ inner=${1}
+ outer=${2}
+
+ rump_server_start $SOCK1 netinet6 gif
+ rump_server_start $SOCK2 netinet6 gif
+
+ router1_lan=""
+ router1_lan_mode=""
+ router2_lan=""
+ router2_lan_mode=""
+ if [ ${inner} = "ipv6" ]; then
+ router1_lan=$ROUTER1_LANIP6
+ router1_lan_mode="ipv6"
+ router2_lan=$ROUTER2_LANIP6
+ router2_lan_mode="ipv6"
+ else
+ router1_lan=$ROUTER1_LANIP
+ router1_lan_mode="ipv4"
+ router2_lan=$ROUTER2_LANIP
+ router2_lan_mode="ipv4"
+ fi
+
+ if [ ${outer} = "ipv6" ]; then
+ setup_router $SOCK1 ${router1_lan} ${router1_lan_mode} \
+ $ROUTER1_WANIP6 ipv6
+ setup_router $SOCK2 ${router2_lan} ${router2_lan_mode} \
+ $ROUTER2_WANIP6 ipv6
+ else
+ setup_router $SOCK1 ${router1_lan} ${router1_lan_mode} \
+ $ROUTER1_WANIP ipv4
+ setup_router $SOCK2 ${router2_lan} ${router2_lan_mode} \
+ $ROUTER2_WANIP ipv4
+ fi
+}
+
+test_setup()
+{
+ inner=${1}
+ outer=${2}
+
+ router1_lan=""
+ router1_lan_mode=""
+ router2_lan=""
+ router2_lan_mode=""
+ if [ ${inner} = "ipv6" ]; then
+ router1_lan=$ROUTER1_LANIP6
+ router1_lan_mode="ipv6"
+ router2_lan=$ROUTER2_LANIP6
+ router2_lan_mode="ipv6"
+ else
+ router1_lan=$ROUTER1_LANIP
+ router1_lan_mode="ipv4"
+ router2_lan=$ROUTER2_LANIP
+ router2_lan_mode="ipv4"
+ fi
+ if [ ${outer} = "ipv6" ]; then
+ test_router $SOCK1 ${router1_lan} ${router1_lan_mode} \
+ $ROUTER1_WANIP6 ipv6
+ test_router $SOCK2 ${router2_lan} ${router2_lan_mode} \
+ $ROUTER2_WANIP6 ipv6
+ else
+ test_router $SOCK1 ${router1_lan} ${router1_lan_mode} \
+ $ROUTER1_WANIP ipv4
+ test_router $SOCK2 ${router2_lan} ${router2_lan_mode} \
+ $ROUTER2_WANIP ipv4
+ fi
+}
+
+setup_if_gif()
+{
+ sock=${1}
+ addr=${2}
+ remote=${3}
+ inner=${4}
+ src=${5}
+ dst=${6}
+ peernet=${7}
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 rump.ifconfig gif0 create
+ atf_check -s exit:0 rump.ifconfig gif0 tunnel ${src} ${dst}
+ if [ ${inner} = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig gif0 inet6 ${addr}/128 ${remote}
+ atf_check -s exit:0 -o ignore rump.route add -inet6 ${peernet} ${addr}
+ else
+ atf_check -s exit:0 rump.ifconfig gif0 inet ${addr}/32 ${remote}
+ atf_check -s exit:0 -o ignore rump.route add -inet ${peernet} ${addr}
+ fi
+
+ rump.ifconfig gif0
+ rump.route -nL show
+}
+
+setup_tunnel()
+{
+ inner=${1}
+ outer=${2}
+
+ addr=""
+ remote=""
+ src=""
+ dst=""
+ peernet=""
+
+ if [ ${inner} = "ipv6" ]; then
+ addr=$ROUTER1_GIFIP6
+ remote=$ROUTER2_GIFIP6
+ peernet=$ROUTER2_LANNET6
+ else
+ addr=$ROUTER1_GIFIP
+ remote=$ROUTER2_GIFIP
+ peernet=$ROUTER2_LANNET
+ fi
+ if [ ${outer} = "ipv6" ]; then
+ src=$ROUTER1_WANIP6
+ dst=$ROUTER2_WANIP6
+ else
+ src=$ROUTER1_WANIP
+ dst=$ROUTER2_WANIP
+ fi
+ setup_if_gif $SOCK1 ${addr} ${remote} ${inner} \
+ ${src} ${dst} ${peernet}
+
+ if [ $inner = "ipv6" ]; then
+ addr=$ROUTER2_GIFIP6
+ remote=$ROUTER1_GIFIP6
+ peernet=$ROUTER1_LANNET6
+ else
+ addr=$ROUTER2_GIFIP
+ remote=$ROUTER1_GIFIP
+ peernet=$ROUTER1_LANNET
+ fi
+ if [ $outer = "ipv6" ]; then
+ src=$ROUTER2_WANIP6
+ dst=$ROUTER1_WANIP6
+ else
+ src=$ROUTER2_WANIP
+ dst=$ROUTER1_WANIP
+ fi
+ setup_if_gif $SOCK2 ${addr} ${remote} ${inner} \
+ ${src} ${dst} ${peernet}
+}
+
+test_setup_tunnel()
+{
+ mode=${1}
+
+ peernet=""
+ opt=""
+ if [ ${mode} = "ipv6" ]; then
+ peernet=$ROUTER2_LANNET6
+ opt="-inet6"
+ else
+ peernet=$ROUTER2_LANNET
+ opt="-inet"
+ fi
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o match:gif0 rump.ifconfig
+ atf_check -s exit:0 -o match:gif0 rump.route -nL get ${opt} ${peernet}
+
+ if [ ${mode} = "ipv6" ]; then
+ peernet=$ROUTER1_LANNET6
+ opt="-inet6"
+ else
+ peernet=$ROUTER1_LANNET
+ opt="-inet"
+ fi
+ export RUMP_SERVER=$SOCK2
+ atf_check -s exit:0 -o match:gif0 rump.ifconfig
+ atf_check -s exit:0 -o match:gif0 rump.route -nL get ${opt} ${peernet}
+}
+
+teardown_tunnel()
+{
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 rump.ifconfig gif0 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif0 destroy
+
+ export RUMP_SERVER=$SOCK2
+ atf_check -s exit:0 rump.ifconfig gif0 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif0 destroy
+}
+
+setup_dummy_if_gif()
+{
+ sock=${1}
+ addr=${2}
+ remote=${3}
+ inner=${4}
+ src=${5}
+ dst=${6}
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 rump.ifconfig gif1 create
+ atf_check -s exit:0 rump.ifconfig gif1 tunnel ${src} ${dst}
+ if [ ${inner} = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig gif1 inet6 ${addr}/128 ${remote}
+ else
+ atf_check -s exit:0 rump.ifconfig gif1 inet ${addr}/32 ${remote}
+ fi
+
+ rump.ifconfig gif1
+}
+
+setup_dummy_tunnel()
+{
+ inner=${1}
+ outer=${2}
+
+ addr=""
+ remote=""
+ src=""
+ dst=""
+
+ if [ ${inner} = "ipv6" ]; then
+ addr=$ROUTER1_GIFIP6_DUMMY
+ remote=$ROUTER2_GIFIP6_DUMMY
+ else
+ addr=$ROUTER1_GIFIP_DUMMY
+ remote=$ROUTER2_GIFIP_DUMMY
+ fi
+ if [ ${outer} = "ipv6" ]; then
+ src=$ROUTER1_WANIP6_DUMMY
+ dst=$ROUTER2_WANIP6_DUMMY
+ else
+ src=$ROUTER1_WANIP_DUMMY
+ dst=$ROUTER2_WANIP_DUMMY
+ fi
+ setup_dummy_if_gif $SOCK1 ${addr} ${remote} ${inner} \
+ ${src} ${dst}
+
+ if [ $inner = "ipv6" ]; then
+ addr=$ROUTER2_GIFIP6_DUMMY
+ remote=$ROUTER1_GIFIP6_DUMMY
+ else
+ addr=$ROUTER2_GIFIP_DUMMY
+ remote=$ROUTER1_GIFIP_DUMMY
+ fi
+ if [ $outer = "ipv6" ]; then
+ src=$ROUTER2_WANIP6_DUMMY
+ dst=$ROUTER1_WANIP6_DUMMY
+ else
+ src=$ROUTER2_WANIP_DUMMY
+ dst=$ROUTER1_WANIP_DUMMY
+ fi
+ setup_dummy_if_gif $SOCK2 ${addr} ${remote} ${inner} \
+ ${src} ${dst}
+}
+
+test_setup_dummy_tunnel()
+{
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 -o match:gif1 rump.ifconfig
+
+ export RUMP_SERVER=$SOCK2
+ atf_check -s exit:0 -o match:gif1 rump.ifconfig
+}
+
+teardown_dummy_tunnel()
+{
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 rump.ifconfig gif1 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif1 destroy
+
+ export RUMP_SERVER=$SOCK2
+ atf_check -s exit:0 rump.ifconfig gif1 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif1 destroy
+}
+
+setup_recursive_if_gif()
+{
+ sock=${1}
+ gif=${2}
+ addr=${3}
+ remote=${4}
+ inner=${5}
+ src=${6}
+ dst=${7}
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 rump.ifconfig ${gif} create
+ atf_check -s exit:0 rump.ifconfig ${gif} tunnel ${src} ${dst}
+ if [ ${inner} = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig ${gif} inet6 ${addr}/128 ${remote}
+ else
+ atf_check -s exit:0 rump.ifconfig ${gif} inet ${addr}/32 ${remote}
+ fi
+
+ rump.ifconfig ${gif}
+}
+
+# test in ROUTER1 only
+setup_recursive_tunnels()
+{
+ mode=${1}
+
+ addr=""
+ remote=""
+ src=""
+ dst=""
+
+ if [ ${mode} = "ipv6" ]; then
+ addr=$ROUTER1_GIFIP6_RECURSIVE1
+ remote=$ROUTER2_GIFIP6_RECURSIVE1
+ src=$ROUTER1_GIFIP6
+ dst=$ROUTER2_GIFIP6
+ else
+ addr=$ROUTER1_GIFIP_RECURSIVE1
+ remote=$ROUTER2_GIFIP_RECURSIVE1
+ src=$ROUTER1_GIFIP
+ dst=$ROUTER2_GIFIP
+ fi
+ setup_recursive_if_gif $SOCK1 gif1 ${addr} ${remote} ${mode} \
+ ${src} ${dst}
+
+ if [ ${mode} = "ipv6" ]; then
+ addr=$ROUTER1_GIFIP6_RECURSIVE2
+ remote=$ROUTER2_GIFIP6_RECURSIVE2
+ src=$ROUTER1_GIFIP6_RECURSIVE1
+ dst=$ROUTER2_GIFIP6_RECURSIVE1
+ else
+ addr=$ROUTER1_GIFIP_RECURSIVE2
+ remote=$ROUTER2_GIFIP_RECURSIVE2
+ src=$ROUTER1_GIFIP_RECURSIVE1
+ dst=$ROUTER2_GIFIP_RECURSIVE1
+ fi
+ setup_recursive_if_gif $SOCK1 gif2 ${addr} ${remote} ${mode} \
+ ${src} ${dst}
+}
+
+# test in router1 only
+test_recursive_check()
+{
+ mode=$1
+
+ export RUMP_SERVER=$SOCK1
+ if [ ${mode} = "ipv6" ]; then
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 $ROUTER2_GIFIP6_RECURSIVE2
+ else
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w $TIMEOUT -c 1 $ROUTER2_GIFIP_RECURSIVE2
+ fi
+
+ atf_check -o match:'gif0: recursively called too many times' \
+ -x "$HIJACKING dmesg"
+
+ $HIJACKING dmesg
+}
+
+teardown_recursive_tunnels()
+{
+ export RUMP_SERVER=$SOCK1
+ atf_check -s exit:0 rump.ifconfig gif1 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif1 destroy
+ atf_check -s exit:0 rump.ifconfig gif2 deletetunnel
+ atf_check -s exit:0 rump.ifconfig gif2 destroy
+}
+
+test_ping_failure()
+{
+ mode=$1
+
+ export RUMP_SERVER=$SOCK1
+ if [ ${mode} = "ipv6" ]; then
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER1_LANIP6 \
+ $ROUTER2_LANIP6
+ else
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
+ $ROUTER2_LANIP
+ fi
+
+ export RUMP_SERVER=$SOCK2
+ if [ ${mode} = "ipv6" ]; then
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER2_LANIP6 \
+ $ROUTER1_LANIP6
+ else
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
+ $ROUTER2_LANIP
+ fi
+}
+
+test_ping_success()
+{
+ mode=$1
+
+ export RUMP_SERVER=$SOCK1
+ rump.ifconfig -v gif0
+ if [ ${mode} = "ipv6" ]; then
+ # XXX
+ # rump.ping6 rarely fails with the message that
+ # "failed to get receiving hop limit".
+ # This is a known issue being analyzed.
+ atf_check -s exit:0 -o ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER1_LANIP6 \
+ $ROUTER2_LANIP6
+ else
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
+ $ROUTER2_LANIP
+ fi
+ rump.ifconfig -v gif0
+
+ export RUMP_SERVER=$SOCK2
+ rump.ifconfig -v gif0
+ if [ ${mode} = "ipv6" ]; then
+ atf_check -s exit:0 -o ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 -S $ROUTER2_LANIP6 \
+ $ROUTER1_LANIP6
+ else
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER2_LANIP \
+ $ROUTER1_LANIP
+ fi
+ rump.ifconfig -v gif0
+}
+
+test_change_tunnel_duplicate()
+{
+ mode=$1
+
+ newsrc=""
+ newdst=""
+ if [ ${mode} = "ipv6" ]; then
+ newsrc=$ROUTER1_WANIP6_DUMMY
+ newdst=$ROUTER2_WANIP6_DUMMY
+ else
+ newsrc=$ROUTER1_WANIP_DUMMY
+ newdst=$ROUTER2_WANIP_DUMMY
+ fi
+ export RUMP_SERVER=$SOCK1
+ rump.ifconfig -v gif0
+ rump.ifconfig -v gif1
+ atf_check -s exit:0 -e match:SIOCSLIFPHYADDR \
+ rump.ifconfig gif0 tunnel ${newsrc} ${newdst}
+ rump.ifconfig -v gif0
+ rump.ifconfig -v gif1
+
+ if [ ${mode} = "ipv6" ]; then
+ newsrc=$ROUTER2_WANIP6_DUMMY
+ newdst=$ROUTER1_WANIP6_DUMMY
+ else
+ newsrc=$ROUTER2_WANIP_DUMMY
+ newdst=$ROUTER1_WANIP_DUMMY
+ fi
+ export RUMP_SERVER=$SOCK2
+ rump.ifconfig -v gif0
+ rump.ifconfig -v gif1
+ atf_check -s exit:0 -e match:SIOCSLIFPHYADDR \
+ rump.ifconfig gif0 tunnel ${newsrc} ${newdst}
+ rump.ifconfig -v gif0
+ rump.ifconfig -v gif1
+}
+
+test_change_tunnel_success()
+{
+ mode=$1
+
+ newsrc=""
+ newdst=""
+ if [ ${mode} = "ipv6" ]; then
+ newsrc=$ROUTER1_WANIP6_DUMMY
+ newdst=$ROUTER2_WANIP6_DUMMY
+ else
+ newsrc=$ROUTER1_WANIP_DUMMY
+ newdst=$ROUTER2_WANIP_DUMMY
+ fi
+ export RUMP_SERVER=$SOCK1
+ rump.ifconfig -v gif0
+ atf_check -s exit:0 \
+ rump.ifconfig gif0 tunnel ${newsrc} ${newdst}
+ rump.ifconfig -v gif0
+
+ if [ ${mode} = "ipv6" ]; then
+ newsrc=$ROUTER2_WANIP6_DUMMY
+ newdst=$ROUTER1_WANIP6_DUMMY
+ else
+ newsrc=$ROUTER2_WANIP_DUMMY
+ newdst=$ROUTER1_WANIP_DUMMY
+ fi
+ export RUMP_SERVER=$SOCK2
+ rump.ifconfig -v gif0
+ atf_check -s exit:0 \
+ rump.ifconfig gif0 tunnel ${newsrc} ${newdst}
+ rump.ifconfig -v gif0
+}
+
+basic_setup()
+{
+ inner=$1
+ outer=$2
+
+ setup ${inner} ${outer}
+ test_setup ${inner} ${outer}
+
+ # Enable once PR kern/49219 is fixed
+ #test_ping_failure
+
+ setup_tunnel ${inner} ${outer}
+ sleep 1
+ test_setup_tunnel ${inner}
+}
+
+basic_test()
+{
+ inner=$1
+ outer=$2 # not use
+
+ test_ping_success ${inner}
+}
+
+basic_teardown()
+{
+ inner=$1
+ outer=$2 # not use
+
+ teardown_tunnel
+ test_ping_failure ${inner}
+}
+
+ioctl_setup()
+{
+ inner=$1
+ outer=$2
+
+ setup ${inner} ${outer}
+ test_setup ${inner} ${outer}
+
+ # Enable once PR kern/49219 is fixed
+ #test_ping_failure
+
+ setup_tunnel ${inner} ${outer}
+ setup_dummy_tunnel ${inner} ${outer}
+ sleep 1
+ test_setup_tunnel ${inner}
+}
+
+ioctl_test()
+{
+ inner=$1
+ outer=$2
+
+ test_ping_success ${inner}
+
+ test_change_tunnel_duplicate ${outer}
+
+ teardown_dummy_tunnel
+ test_change_tunnel_success ${outer}
+}
+
+ioctl_teardown()
+{
+ inner=$1
+ outer=$2 # not use
+
+ teardown_tunnel
+ test_ping_failure ${inner}
+}
+
+recursive_setup()
+{
+ inner=$1
+ outer=$2
+
+ setup ${inner} ${outer}
+ test_setup ${inner} ${outer}
+
+ # Enable once PR kern/49219 is fixed
+ #test_ping_failure
+
+ setup_tunnel ${inner} ${outer}
+ setup_recursive_tunnels ${inner}
+ sleep 1
+ test_setup_tunnel ${inner}
+}
+
+recursive_test()
+{
+ inner=$1
+ outer=$2 # not use
+
+ test_recursive_check ${inner}
+}
+
+recursive_teardown()
+{
+ inner=$1 # not use
+ outer=$2 # not use
+
+ teardown_recursive_tunnels
+ teardown_tunnel
+}
+
+add_test()
+{
+ category=$1
+ desc=$2
+ inner=$3
+ outer=$4
+
+ name="gif_${category}_${inner}over${outer}"
+ fulldesc="Does ${inner} over ${outer} if_gif ${desc}"
+
+ atf_test_case ${name} cleanup
+ eval "${name}_head() { \
+ atf_set \"descr\" \"${fulldesc}\"; \
+ atf_set \"require.progs\" \"rump_server\"; \
+ }; \
+ ${name}_body() { \
+ ${category}_setup ${inner} ${outer}; \
+ ${category}_test ${inner} ${outer}; \
+ ${category}_teardown ${inner} ${outer}; \
+ rump_server_destroy_ifaces; \
+ }; \
+ ${name}_cleanup() { \
+ $DEBUG && dump; \
+ cleanup; \
+ }"
+ atf_add_test_case ${name}
+}
+
+add_test_allproto()
+{
+ category=$1
+ desc=$2
+
+ add_test ${category} "${desc}" ipv4 ipv4
+ add_test ${category} "${desc}" ipv4 ipv6
+ add_test ${category} "${desc}" ipv6 ipv4
+ add_test ${category} "${desc}" ipv6 ipv6
+}
+
+atf_init_test_cases()
+{
+ add_test_allproto basic "basic tests"
+ add_test_allproto ioctl "ioctl tests"
+ add_test_allproto recursive "recursive check tests"
+}
diff --git a/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh b/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh
new file mode 100755
index 0000000..8d9d5c2
--- /dev/null
+++ b/contrib/netbsd-tests/net/if_pppoe/t_pppoe.sh
@@ -0,0 +1,416 @@
+# $NetBSD: t_pppoe.sh,v 1.16 2016/12/14 03:30:30 knakahara Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+server="rump_server -lrump -lrumpnet -lrumpnet_net -lrumpnet_netinet \
+ -lrumpnet_netinet6 -lrumpnet_shmif -lrumpdev \
+ -lrumpnet_pppoe"
+# pppoectl doesn't work with RUMPHIJACK=sysctl=yes
+HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so"
+
+SERVER=unix://commsock1
+CLIENT=unix://commsock2
+
+SERVER_IP=10.3.3.1
+CLIENT_IP=10.3.3.3
+SERVER_IP6=fc00::1
+CLIENT_IP6=fc00::3
+AUTHNAME=foobar@baz.com
+SECRET=oink
+BUS=bus0
+TIMEOUT=3
+WAITTIME=10
+DEBUG=${DEBUG:-false}
+
+setup()
+{
+ inet=true
+
+ if [ $# -ne 0 ]; then
+ eval $@
+ fi
+
+ atf_check -s exit:0 ${server} $SERVER
+ atf_check -s exit:0 ${server} $CLIENT
+
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 rump.ifconfig pppoe0 create
+ $inet && atf_check -s exit:0 rump.ifconfig pppoe0 \
+ inet $SERVER_IP $CLIENT_IP down
+ atf_check -s exit:0 rump.ifconfig pppoe0 link0
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+
+ atf_check -s exit:0 -x "$HIJACKING pppoectl -e shmif0 pppoe0"
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr $BUS
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 rump.ifconfig pppoe0 create
+ $inet && atf_check -s exit:0 rump.ifconfig pppoe0 \
+ inet 0.0.0.0 0.0.0.1 down
+
+ atf_check -s exit:0 -x "$HIJACKING pppoectl -e shmif0 pppoe0"
+ unset RUMP_SERVER
+}
+
+cleanup()
+{
+ env RUMP_SERVER=$SERVER rump.halt
+ env RUMP_SERVER=$CLIENT rump.halt
+}
+
+
+wait_for_session_established()
+{
+ local dontfail=$1
+ local n=$WAITTIME
+
+ for i in $(seq $n); do
+ $HIJACKING pppoectl -d pppoe0 |grep -q "state = session"
+ [ $? = 0 ] && return
+ sleep 1
+ done
+
+ if [ "$dontfail" != "dontfail" ]; then
+ atf_fail "Couldn't connect to the server for $n seconds."
+ fi
+}
+
+wait_for_disconnected()
+{
+ local dontfail=$1
+ local n=$WAITTIME
+
+ for i in $(seq $n); do
+ $HIJACKING pppoectl -d pppoe0 | grep -q "state = initial"
+ [ $? = 0 ] && return
+ # If PPPoE client is disconnected by PPPoE server and then
+ # the client kicks callout of pppoe_timeout(), the client
+ # state is changed to PPPOE_STATE_PADI_SENT while padi retrying.
+ $HIJACKING pppoectl -d pppoe0 | grep -q "state = PADI sent"
+ [ $? = 0 ] && return
+
+ sleep 1
+ done
+
+ if [ "$dontfail" != "dontfail" ]; then
+ atf_fail "Couldn't disconnect for $n seconds."
+ fi
+}
+
+run_test()
+{
+ local auth=$1
+ setup
+
+ # As pppoe client doesn't support rechallenge yet.
+ local server_optparam=""
+ if [ $auth = "chap" ]; then
+ server_optparam="norechallenge"
+ fi
+
+ export RUMP_SERVER=$SERVER
+ local setup_serverparam="pppoectl pppoe0 hisauthproto=$auth \
+ 'hisauthname=$AUTHNAME' \
+ 'hisauthsecret=$SECRET' \
+ 'myauthproto=none' \
+ $server_optparam"
+ atf_check -s exit:0 -x "$HIJACKING $setup_serverparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$CLIENT
+ local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \
+ 'myauthname=$AUTHNAME' \
+ 'myauthsecret=$SECRET' \
+ 'hisauthproto=none'"
+ atf_check -s exit:0 -x "$HIJACKING $setup_clientparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ $DEBUG && rump.ifconfig
+ wait_for_session_established
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $SERVER_IP
+ unset RUMP_SERVER
+
+ # test for disconnection from server
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 rump.ifconfig pppoe0 down
+ wait_for_disconnected
+ export RUMP_SERVER=$CLIENT
+ wait_for_disconnected
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -c 1 -w $TIMEOUT $SERVER_IP
+ atf_check -s exit:0 -o match:'PADI sent' -x "$HIJACKING pppoectl -d pppoe0"
+ unset RUMP_SERVER
+
+ # test for recoonecting
+ atf_check -s exit:0 -x "env RUMP_SERVER=$SERVER rump.ifconfig pppoe0 up"
+ export RUMP_SERVER=$CLIENT
+ wait_for_session_established
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $SERVER_IP
+ unset RUMP_SERVER
+
+ # test for disconnection from client
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 -x rump.ifconfig pppoe0 down
+ wait_for_disconnected
+ export RUMP_SERVER=$SERVER
+ wait_for_disconnected
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -c 1 -w $TIMEOUT $CLIENT_IP
+ atf_check -s exit:0 -o match:'initial' -x "$HIJACKING pppoectl -d pppoe0"
+ unset RUMP_SERVER
+
+ # test for reconnecting
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 -x rump.ifconfig pppoe0 up
+ wait_for_session_established
+ $DEBUG && rump.ifconfig pppoe0
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 rump.ifconfig -w 10
+ atf_check -s exit:0 -o ignore rump.ping -c 1 -w $TIMEOUT $CLIENT_IP
+ atf_check -s exit:0 -o match:'session' -x "$HIJACKING pppoectl -d pppoe0"
+ $DEBUG && HIJACKING pppoectl -d pppoe0
+ unset RUMP_SERVER
+
+ # test for invalid password
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 rump.ifconfig pppoe0 down
+ wait_for_disconnected
+ local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \
+ 'myauthname=$AUTHNAME' \
+ 'myauthsecret=invalidsecret' \
+ 'hisauthproto=none'"
+ atf_check -s exit:0 -x "$HIJACKING $setup_clientparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ wait_for_session_established dontfail
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -c 1 -w $TIMEOUT $SERVER_IP
+ atf_check -s exit:0 -o match:'DETACHED' rump.ifconfig pppoe0
+ unset RUMP_SERVER
+}
+
+atf_test_case pppoe_pap cleanup
+
+pppoe_pap_head()
+{
+ atf_set "descr" "Does simple pap tests"
+ atf_set "require.progs" "rump_server pppoectl"
+}
+
+pppoe_pap_body()
+{
+ run_test pap
+}
+
+pppoe_pap_cleanup()
+{
+ cleanup
+}
+
+atf_test_case pppoe_chap cleanup
+
+pppoe_chap_head()
+{
+ atf_set "descr" "Does simple chap tests"
+ atf_set "require.progs" "rump_server pppoectl"
+}
+
+pppoe_chap_body()
+{
+ run_test chap
+}
+
+pppoe_chap_cleanup()
+{
+ cleanup
+}
+
+run_test6()
+{
+ local auth=$1
+ setup "inet=false"
+
+ # As pppoe client doesn't support rechallenge yet.
+ local server_optparam=""
+ if [ $auth = "chap" ]; then
+ server_optparam="norechallenge"
+ fi
+
+ export RUMP_SERVER=$SERVER
+ local setup_serverparam="pppoectl pppoe0 hisauthproto=$auth \
+ 'hisauthname=$AUTHNAME' \
+ 'hisauthsecret=$SECRET' \
+ 'myauthproto=none' \
+ $server_optparam"
+ atf_check -s exit:0 -x "$HIJACKING $setup_serverparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 inet6 $SERVER_IP6/64 down
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$CLIENT
+ local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \
+ 'myauthname=$AUTHNAME' \
+ 'myauthsecret=$SECRET' \
+ 'hisauthproto=none'"
+ atf_check -s exit:0 -x "$HIJACKING $setup_clientparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 inet6 $CLIENT_IP6/64 down
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ $DEBUG && rump.ifconfig
+ wait_for_session_established
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6
+ unset RUMP_SERVER
+
+ # test for disconnection from server
+ export RUMP_SERVER=$SERVER
+ session_id=`$HIJACKING pppoectl -d pppoe0 | grep state`
+ atf_check -s exit:0 rump.ifconfig pppoe0 down
+ wait_for_disconnected
+ export RUMP_SERVER=$CLIENT
+ wait_for_disconnected
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6
+ atf_check -s exit:0 -o not-match:"$session_id" -x "$HIJACKING pppoectl -d pppoe0"
+ unset RUMP_SERVER
+
+ # test for recoonecting
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ wait_for_session_established
+ atf_check -s exit:0 rump.ifconfig -w 10
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+ $DEBUG && rump.ifconfig pppoe0
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6
+ unset RUMP_SERVER
+
+ # test for disconnection from client
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 rump.ifconfig pppoe0 down
+ wait_for_disconnected
+
+ export RUMP_SERVER=$SERVER
+ wait_for_disconnected
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -c 1 -X $TIMEOUT $CLIENT_IP6
+ atf_check -s exit:0 -o match:'initial' -x "$HIJACKING pppoectl -d pppoe0"
+ unset RUMP_SERVER
+
+ # test for reconnecting
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ wait_for_session_established
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig pppoe0
+ $DEBUG && $HIJACKING pppoectl -d pppoe0
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$SERVER
+ atf_check -s exit:0 rump.ifconfig -w 10
+ atf_check -s exit:0 -o ignore rump.ping6 -c 1 -X $TIMEOUT $CLIENT_IP6
+ atf_check -s exit:0 -o match:'session' -x "$HIJACKING pppoectl -d pppoe0"
+ $DEBUG && HIJACKING pppoectl -d pppoe0
+ unset RUMP_SERVER
+
+ # test for invalid password
+ export RUMP_SERVER=$CLIENT
+ atf_check -s exit:0 rump.ifconfig pppoe0 down
+ wait_for_disconnected
+ local setup_clientparam="pppoectl pppoe0 myauthproto=$auth \
+ 'myauthname=$AUTHNAME' \
+ 'myauthsecret=invalidsecret' \
+ 'hisauthproto=none'"
+ atf_check -s exit:0 -x "$HIJACKING $setup_clientparam"
+ atf_check -s exit:0 rump.ifconfig pppoe0 up
+ wait_for_session_established dontfail
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -c 1 -X $TIMEOUT $SERVER_IP6
+ atf_check -s exit:0 -o match:'DETACHED' rump.ifconfig pppoe0
+ unset RUMP_SERVER
+}
+
+atf_test_case pppoe6_pap cleanup
+
+pppoe6_pap_head()
+{
+ atf_set "descr" "Does simple pap using IPv6 tests"
+ atf_set "require.progs" "rump_server pppoectl"
+}
+
+pppoe6_pap_body()
+{
+ run_test6 pap
+}
+
+pppoe6_pap_cleanup()
+{
+ cleanup
+}
+
+atf_test_case pppoe6_chap cleanup
+
+pppoe6_chap_head()
+{
+ atf_set "descr" "Does simple chap using IPv6 tests"
+ atf_set "require.progs" "rump_server pppoectl"
+}
+
+pppoe6_chap_body()
+{
+ run_test6 chap
+}
+
+pppoe6_chap_cleanup()
+{
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case pppoe_pap
+ atf_add_test_case pppoe_chap
+ atf_add_test_case pppoe6_pap
+ atf_add_test_case pppoe6_chap
+}
diff --git a/contrib/netbsd-tests/net/if_tap/t_tap.sh b/contrib/netbsd-tests/net/if_tap/t_tap.sh
new file mode 100755
index 0000000..4b1ce25
--- /dev/null
+++ b/contrib/netbsd-tests/net/if_tap/t_tap.sh
@@ -0,0 +1,198 @@
+# $NetBSD: t_tap.sh,v 1.6 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK_LOCAL=unix://commsock1
+SOCK_REMOTE=unix://commsock2
+BUS=bus1
+IP4_LOCAL=10.0.0.1
+IP4_TAP=10.0.0.2
+IP4_REMOTE=10.0.0.3
+IP6_LOCAL=fc00::1
+IP6_TAP=fc00::2
+IP6_REMOTE=fc00::3
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=1
+
+atf_test_case tap_create_destroy cleanup
+tap_create_destroy_head()
+{
+
+ atf_set "descr" "tests of creation and deletion of tap interface"
+ atf_set "require.progs" "rump_server"
+}
+
+tap_create_destroy_body()
+{
+
+ rump_server_start $SOCK_LOCAL netinet6 tap
+
+ export RUMP_SERVER=${SOCK_LOCAL}
+
+ # Create and destroy (no address)
+ atf_check -s exit:0 rump.ifconfig tap0 create
+ atf_check -s exit:0 rump.ifconfig tap0 destroy
+
+ # Create and destroy (with an IPv4 address)
+ atf_check -s exit:0 rump.ifconfig tap0 create
+ atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 up
+ atf_check -s exit:0 rump.ifconfig tap0 destroy
+
+ # Create and destroy (with an IPv6 address)
+ atf_check -s exit:0 rump.ifconfig tap0 create
+ atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 up
+ atf_check -s exit:0 rump.ifconfig tap0 destroy
+}
+
+tap_create_destroy_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case tap_stand_alone cleanup
+tap_create_destroy_head()
+{
+
+ atf_set "descr" "tests of alone tap interface"
+ atf_set "require.progs" "rump_server"
+}
+
+tap_stand_alone_body()
+{
+
+ rump_server_start $SOCK_LOCAL netinet6 tap
+ rump_server_start $SOCK_REMOTE netinet6 tap
+
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+ rump_server_add_iface $SOCK_REMOTE shmif0 $BUS
+
+ export RUMP_SERVER=${SOCK_LOCAL}
+ atf_check -s exit:0 rump.ifconfig shmif0 $IP4_LOCAL
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_LOCAL
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig tap0 create
+ atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ export RUMP_SERVER=${SOCK_REMOTE}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 $IP4_REMOTE
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_REMOTE
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_LOCAL
+ # Cannot reach to an alone tap
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping -n -w $TIMEOUT -c 1 $IP4_TAP
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_LOCAL
+ # Cannot reach to an alone tap
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -n -X $TIMEOUT -c 1 $IP6_TAP
+
+ rump_server_destroy_ifaces
+}
+
+tap_stand_alone_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case tap_bridged cleanup
+tap_bridged_head()
+{
+
+ atf_set "descr" "tests of alone tap interface"
+ atf_set "require.progs" "rump_server"
+}
+
+tap_bridged_body()
+{
+
+ rump_server_start $SOCK_LOCAL netinet6 tap bridge
+ rump_server_start $SOCK_REMOTE netinet6 tap
+
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+ rump_server_add_iface $SOCK_REMOTE shmif0 $BUS
+
+ export RUMP_SERVER=${SOCK_LOCAL}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 $IP4_LOCAL
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_LOCAL
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig tap0 create
+ atf_check -s exit:0 rump.ifconfig tap0 $IP4_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 inet6 $IP6_TAP
+ atf_check -s exit:0 rump.ifconfig tap0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ atf_check -s exit:0 rump.ifconfig bridge0 create
+ atf_check -s exit:0 rump.ifconfig bridge0 up
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ atf_check -s exit:0 brconfig bridge0 add shmif0
+ atf_check -s exit:0 brconfig bridge0 add tap0
+ unset LD_PRELOAD
+
+ export RUMP_SERVER=${SOCK_REMOTE}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 $IP4_REMOTE
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6_REMOTE
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_LOCAL
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 $IP4_TAP
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_LOCAL
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6_TAP
+
+ rump_server_destroy_ifaces
+}
+
+tap_bridged_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case tap_create_destroy
+ atf_add_test_case tap_stand_alone
+ atf_add_test_case tap_bridged
+}
diff --git a/contrib/netbsd-tests/net/in_cksum/assym.h b/contrib/netbsd-tests/net/in_cksum/assym.h
new file mode 100644
index 0000000..60aa41f
--- /dev/null
+++ b/contrib/netbsd-tests/net/in_cksum/assym.h
@@ -0,0 +1,10 @@
+/* XXX: Depends on m_hdr */
+#ifdef _LP64
+#define M_NEXT 0
+#define M_DATA 16
+#define M_LEN 32
+#else
+#define M_NEXT 0
+#define M_DATA 8
+#define M_LEN 16
+#endif
diff --git a/contrib/netbsd-tests/net/in_cksum/in_cksum.c b/contrib/netbsd-tests/net/in_cksum/in_cksum.c
new file mode 100644
index 0000000..4bdaf5b
--- /dev/null
+++ b/contrib/netbsd-tests/net/in_cksum/in_cksum.c
@@ -0,0 +1,270 @@
+/* $NetBSD: in_cksum.c,v 1.5 2015/10/18 18:27:25 christos Exp $ */
+/*-
+ * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``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
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS 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/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: in_cksum.c,v 1.5 2015/10/18 18:27:25 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sys/resource.h>
+#include <err.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define cpu_in_cksum portable_cpu_in_cksum
+#include "cpu_in_cksum.c"
+
+#ifdef HAVE_CPU_IN_CKSUM
+#undef cpu_in_cksum
+int cpu_in_cksum(struct mbuf*, int, int, uint32_t);
+#endif
+
+static bool random_aligned;
+
+void panic(const char *, ...) __printflike(1, 2);
+void
+panic(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(1, fmt, ap);
+ va_end(ap);
+}
+
+static void
+free_mbuf_chain(struct mbuf *m)
+{
+ struct mbuf *next;
+
+ if (m == NULL)
+ return;
+
+ next = m->m_next;
+ free(m);
+ free_mbuf_chain(next);
+}
+
+static struct mbuf *
+allocate_mbuf_chain(char **lens)
+{
+ int len, off;
+ struct mbuf *m;
+
+ if (*lens == NULL)
+ return NULL;
+
+ len = atoi(*lens);
+ off = random_aligned ? rand() % 64 : 0;
+
+ m = malloc(sizeof(struct m_hdr) + len + off);
+ if (m == NULL)
+ err(EXIT_FAILURE, "malloc failed");
+
+ m->m_data = (char *)m + sizeof(struct m_hdr) + off;
+ m->m_len = len;
+
+ m->m_next = allocate_mbuf_chain(lens + 1);
+
+ return m;
+}
+
+#ifdef MBUFDUMP
+static void
+dump_mbuf(const struct mbuf *m, int len, int off)
+{
+ int x = 0;
+ if (len <= 0)
+ return;
+
+ printf("Starting len=%d off=%d:\n", len, off);
+ if (off > 0) {
+ for (; m; m = m->m_next)
+ if (off > m->m_len)
+ off -= m->m_len;
+ else
+ break;
+ if (m == NULL || off > m->m_len)
+ errx(1, "out of data");
+ }
+
+ unsigned char *ptr = mtod(m, unsigned char *) + off;
+ unsigned char *eptr = ptr + m->m_len;
+ printf("[");
+ for (;;) {
+ if (ptr == eptr) {
+ m = m->m_next;
+ if (m == NULL)
+ errx(1, "out of data");
+ ptr = mtod(m, unsigned char *);
+ eptr = ptr + m->m_len;
+ printf("]\n[");
+ x = 0;
+ }
+ printf("%.2x ", *ptr++);
+ if (++x % 16 == 0)
+ printf("\n");
+ if (--len == 0)
+ break;
+ }
+ printf("]\n");
+ fflush(stdout);
+}
+#endif
+
+static void
+randomise_mbuf_chain(struct mbuf *m)
+{
+ int i, data, len;
+
+ for (i = 0; i < m->m_len; i += sizeof(int)) {
+ data = rand();
+ if (i + sizeof(int) < (size_t)m->m_len)
+ len = sizeof(int);
+ else
+ len = m->m_len - i;
+ memcpy(m->m_data + i, &data, len);
+ }
+ if (m->m_next)
+ randomise_mbuf_chain(m->m_next);
+}
+
+static int
+mbuf_len(struct mbuf *m)
+{
+ return m == NULL ? 0 : m->m_len + mbuf_len(m->m_next);
+}
+
+int in_cksum_portable(struct mbuf *, int);
+int in_cksum(struct mbuf *, int);
+
+int
+main(int argc, char **argv)
+{
+ struct rusage res;
+ struct timeval tv, old_tv;
+ int loops, old_sum, off, len;
+#ifdef HAVE_CPU_IN_CKSUM
+ int new_sum;
+#endif
+ long i, iterations;
+ uint32_t init_sum;
+ struct mbuf *m;
+ bool verbose;
+ int c;
+
+ loops = 16;
+ verbose = false;
+ random_aligned = 0;
+ iterations = 100000;
+
+ while ((c = getopt(argc, argv, "i:l:u:v")) != -1) {
+ switch (c) {
+ case 'i':
+ iterations = atoi(optarg);
+ break;
+ case 'l':
+ loops = atoi(optarg);
+ break;
+ case 'u':
+ random_aligned = atoi(optarg);
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ errx(1, "%s [-l <loops>] [-u <unalign> [-i <iterations> "
+ "[<mbuf-size> ...]", getprogname());
+ }
+ }
+
+ for (; loops; --loops) {
+ if ((m = allocate_mbuf_chain(argv + 4)) == NULL)
+ continue;
+ randomise_mbuf_chain(m);
+ init_sum = rand();
+ len = mbuf_len(m);
+
+ /* force one loop over all data */
+ if (loops == 1)
+ off = 0;
+ else
+ off = len ? rand() % len : 0;
+
+ len -= off;
+ old_sum = portable_cpu_in_cksum(m, len, off, init_sum);
+#ifdef HAVE_CPU_IN_CKSUM
+#ifdef MBUFDUMP
+ printf("m->m_len=%d len=%d off=%d\n", m->m_len, len, off);
+ dump_mbuf(m, len, off);
+#endif
+ new_sum = cpu_in_cksum(m, len, off, init_sum);
+ if (old_sum != new_sum)
+ errx(1, "comparison failed: %x %x", old_sum, new_sum);
+#else
+ __USE(old_sum);
+#endif
+
+ if (iterations == 0)
+ continue;
+
+ getrusage(RUSAGE_SELF, &res);
+ tv = res.ru_utime;
+ for (i = iterations; i; --i)
+ (void)portable_cpu_in_cksum(m, len, off, init_sum);
+ getrusage(RUSAGE_SELF, &res);
+ timersub(&res.ru_utime, &tv, &old_tv);
+ if (verbose)
+ printf("portable version: %jd.%06jd\n",
+ (intmax_t)old_tv.tv_sec, (intmax_t)old_tv.tv_usec);
+
+#ifdef HAVE_CPU_IN_CKSUM
+ getrusage(RUSAGE_SELF, &res);
+ tv = res.ru_utime;
+ for (i = iterations; i; --i)
+ (void)cpu_in_cksum(m, len, off, init_sum);
+ getrusage(RUSAGE_SELF, &res);
+ timersub(&res.ru_utime, &tv, &tv);
+ if (verbose) {
+ printf("test version: %jd.%06jd\n",
+ (intmax_t)tv.tv_sec, (intmax_t)tv.tv_usec);
+ printf("relative time: %3.g%%\n",
+ 100 * ((double)tv.tv_sec * 1e6 + tv.tv_usec) /
+ ((double)old_tv.tv_sec * 1e6 + old_tv.tv_usec + 1));
+ }
+#endif
+ free_mbuf_chain(m);
+ }
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh b/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh
new file mode 100755
index 0000000..a342403
--- /dev/null
+++ b/contrib/netbsd-tests/net/in_cksum/t_in_cksum.sh
@@ -0,0 +1,78 @@
+#! /usr/bin/atf-sh
+# $NetBSD: t_in_cksum.sh,v 1.2 2015/01/06 15:13:16 martin Exp $
+#
+
+TIMING_LOOPS=10000
+incksum="$(atf_get_srcdir)/in_cksum"
+
+fail() {
+ atf_fail "see output for details"
+}
+
+mbufs() {
+ ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 \
+ || fail
+ ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \
+ || fail
+ ${incksum} -l 64 -u $0 -i ${TIMING_LOOPS} \
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \
+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \
+ || fail
+ ${incksum} -l 16 -u $0 -i ${TIMING_LOOPS} \
+ 1 3 1 3 1 3 1 \
+ || fail
+}
+
+sizes() {
+ ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 2048 || fail
+ ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 40 || fail
+ ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 1536 || fail
+ ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 576 || fail
+ ${incksum} -l 16 -u $1 -i ${TIMING_LOOPS} 1536 1536 1536 1536 1536 640 \
+ || fail
+}
+
+atf_test_case mbufs_aligned
+
+mbufs_aligned_head() {
+ atf_set "descr" "Test in_cksum mbuf chains aligned"
+}
+
+mbufs_aligned_body() {
+ mbufs 0
+}
+
+mbufs_unaligned_head() {
+ atf_set "descr" "Test in_cksum mbuf chains unaligned"
+}
+
+mbufs_unaligned_body() {
+ mbufs 1
+}
+
+sizes_aligned_head() {
+ atf_set "descr" "Test in_cksum sizes aligned"
+}
+
+sizes_aligned_body() {
+ sizes 0
+}
+
+sizes_unaligned_head() {
+ atf_set "descr" "Test in_cksum sizes unaligned"
+}
+
+sizes_unaligned_body() {
+ sizes 1
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case mbufs_aligned
+ atf_add_test_case mbufs_unaligned
+ atf_add_test_case sizes_aligned
+ atf_add_test_case sizes_unaligned
+}
diff --git a/contrib/netbsd-tests/net/mcast/mcast.c b/contrib/netbsd-tests/net/mcast/mcast.c
new file mode 100644
index 0000000..ad2c9b3
--- /dev/null
+++ b/contrib/netbsd-tests/net/mcast/mcast.c
@@ -0,0 +1,559 @@
+/* $NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 FOUNDATION OR CONTRIBUTORS
+ * 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/cdefs.h>
+#ifdef __RCSID
+__RCSID("$NetBSD: mcast.c,v 1.3 2015/05/28 10:19:17 ozaki-r Exp $");
+#else
+extern const char *__progname;
+#define getprogname() __progname
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+
+#include <assert.h>
+#include <netdb.h>
+#include <time.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdbool.h>
+
+#ifdef ATF
+#include <atf-c.h>
+
+#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
+#define ERRX0(ev, msg) ATF_REQUIRE_MSG(0, msg)
+
+#define SKIPX(ev, msg, ...) do { \
+ atf_tc_skip(msg, __VA_ARGS__); \
+ return; \
+} while(/*CONSTCOND*/0)
+
+#else
+#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#define ERRX0(ev, msg) errx(ev, msg)
+#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#endif
+
+static int debug;
+
+#define TOTAL 10
+#define PORT_V4MAPPED "6666"
+#define HOST_V4MAPPED "::FFFF:239.1.1.1"
+#define PORT_V4 "6666"
+#define HOST_V4 "239.1.1.1"
+#define PORT_V6 "6666"
+#define HOST_V6 "FF05:1:0:0:0:0:0:1"
+
+struct message {
+ size_t seq;
+ struct timespec ts;
+};
+
+static int
+addmc(int s, struct addrinfo *ai, bool bug)
+{
+ struct ip_mreq m4;
+ struct ipv6_mreq m6;
+ struct sockaddr_in *s4;
+ struct sockaddr_in6 *s6;
+ unsigned int ifc;
+
+ switch (ai->ai_family) {
+ case AF_INET:
+ s4 = (void *)ai->ai_addr;
+ assert(sizeof(*s4) == ai->ai_addrlen);
+ m4.imr_multiaddr = s4->sin_addr;
+ m4.imr_interface.s_addr = htonl(INADDR_ANY);
+ return setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &m4, sizeof(m4));
+ case AF_INET6:
+ s6 = (void *)ai->ai_addr;
+ /*
+ * Linux: Does not support the v6 ioctls on v4 mapped
+ * sockets but it does support the v4 ones and
+ * it works.
+ * MacOS/X: Supports the v6 ioctls on v4 mapped sockets,
+ * but does not work and also does not support
+ * the v4 ioctls. So no way to make multicasting
+ * work with mapped addresses.
+ * NetBSD: Supports both and works for both.
+ */
+ if (bug && IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) {
+ memcpy(&m4.imr_multiaddr, &s6->sin6_addr.s6_addr[12],
+ sizeof(m4.imr_multiaddr));
+ m4.imr_interface.s_addr = htonl(INADDR_ANY);
+ return setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &m4, sizeof(m4));
+ }
+ assert(sizeof(*s6) == ai->ai_addrlen);
+ memset(&m6, 0, sizeof(m6));
+#if 0
+ ifc = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ &ifc, sizeof(ifc)) == -1)
+ return -1;
+ ifc = 224;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+ &ifc, sizeof(ifc)) == -1)
+ return -1;
+ ifc = 1; /* XXX should pick a proper interface */
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifc,
+ sizeof(ifc)) == -1)
+ return -1;
+#else
+ ifc = 0; /* Let pick an appropriate interface */
+#endif
+ m6.ipv6mr_interface = ifc;
+ m6.ipv6mr_multiaddr = s6->sin6_addr;
+ return setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP,
+ &m6, sizeof(m6));
+ default:
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+}
+
+static int
+allowv4mapped(int s, struct addrinfo *ai)
+{
+ struct sockaddr_in6 *s6;
+ int zero = 0;
+
+ if (ai->ai_family != AF_INET6)
+ return 0;
+
+ s6 = (void *)ai->ai_addr;
+
+ if (!IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr))
+ return 0;
+ return setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero));
+}
+
+static struct sockaddr_storage ss;
+static int
+connector(int fd, const struct sockaddr *sa, socklen_t slen)
+{
+ assert(sizeof(ss) > slen);
+ memcpy(&ss, sa, slen);
+ return 0;
+}
+
+static void
+show(const char *prefix, const struct message *msg)
+{
+ printf("%10.10s: %zu [%jd.%ld]\n", prefix, msg->seq, (intmax_t)
+ msg->ts.tv_sec, msg->ts.tv_nsec);
+}
+
+static int
+getsocket(const char *host, const char *port,
+ int (*f)(int, const struct sockaddr *, socklen_t), socklen_t *slen,
+ bool bug)
+{
+ int e, s, lasterrno = 0;
+ struct addrinfo hints, *ai0, *ai;
+ const char *cause = "?";
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ e = getaddrinfo(host, port, &hints, &ai0);
+ if (e)
+ ERRX(EXIT_FAILURE, "Can't resolve %s:%s (%s)", host, port,
+ gai_strerror(e));
+
+ s = -1;
+ for (ai = ai0; ai; ai = ai->ai_next) {
+ s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+ if (s == -1) {
+ lasterrno = errno;
+ cause = "socket";
+ continue;
+ }
+ if (allowv4mapped(s, ai) == -1) {
+ cause = "allow v4 mapped";
+ goto out;
+ }
+ if ((*f)(s, ai->ai_addr, ai->ai_addrlen) == -1) {
+ cause = f == bind ? "bind" : "connect";
+ goto out;
+ }
+ if ((f == bind || f == connector) && addmc(s, ai, bug) == -1) {
+ cause = "join group";
+ goto out;
+ }
+ *slen = ai->ai_addrlen;
+ break;
+out:
+ lasterrno = errno;
+ close(s);
+ s = -1;
+ continue;
+ }
+ freeaddrinfo(ai0);
+ if (s == -1)
+ ERRX(EXIT_FAILURE, "%s (%s)", cause, strerror(lasterrno));
+ return s;
+}
+
+static int
+synchronize(const int fd, bool waiter)
+{
+ int syncmsg = 0;
+ int r;
+ struct pollfd pfd;
+
+ if (waiter) {
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ /* We use poll to avoid lock up when the peer died unexpectedly */
+ r = poll(&pfd, 1, 10000);
+ if (r == -1)
+ ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno));
+ if (r == 0)
+ /* Timed out */
+ return -1;
+
+ if (read(fd, &syncmsg, sizeof(syncmsg)) == -1)
+ ERRX(EXIT_FAILURE, "read (%s)", strerror(errno));
+ } else {
+ if (write(fd, &syncmsg, sizeof(syncmsg)) == -1)
+ ERRX(EXIT_FAILURE, "write (%s)", strerror(errno));
+ }
+
+ return 0;
+}
+
+static int
+sender(const int fd, const char *host, const char *port, size_t n, bool conn,
+ bool bug)
+{
+ int s;
+ ssize_t l;
+ struct message msg;
+
+ socklen_t slen;
+
+ s = getsocket(host, port, conn ? connect : connector, &slen, bug);
+
+ /* Wait until receiver gets ready. */
+ if (synchronize(fd, true) == -1)
+ return -1;
+
+ for (msg.seq = 0; msg.seq < n; msg.seq++) {
+#ifdef CLOCK_MONOTONIC
+ if (clock_gettime(CLOCK_MONOTONIC, &msg.ts) == -1)
+ ERRX(EXIT_FAILURE, "clock (%s)", strerror(errno));
+#else
+ struct timeval tv;
+ if (gettimeofday(&tv, NULL) == -1)
+ ERRX(EXIT_FAILURE, "clock (%s)", strerror(errno));
+ msg.ts.tv_sec = tv.tv_sec;
+ msg.ts.tv_nsec = tv.tv_usec * 1000;
+#endif
+ if (debug)
+ show("sending", &msg);
+ l = conn ? send(s, &msg, sizeof(msg), 0) :
+ sendto(s, &msg, sizeof(msg), 0, (void *)&ss, slen);
+ if (l == -1)
+ ERRX(EXIT_FAILURE, "send (%s)", strerror(errno));
+ usleep(100);
+ }
+
+ /* Wait until receiver finishes its work. */
+ if (synchronize(fd, true) == -1)
+ return -1;
+
+ return 0;
+}
+
+static void
+receiver(const int fd, const char *host, const char *port, size_t n, bool conn,
+ bool bug)
+{
+ int s;
+ ssize_t l;
+ size_t seq;
+ struct message msg;
+ struct pollfd pfd;
+ socklen_t slen;
+
+ s = getsocket(host, port, bind, &slen, bug);
+ pfd.fd = s;
+ pfd.events = POLLIN;
+
+ /* Tell I'm ready */
+ synchronize(fd, false);
+
+ for (seq = 0; seq < n; seq++) {
+ if (poll(&pfd, 1, 10000) == -1)
+ ERRX(EXIT_FAILURE, "poll (%s)", strerror(errno));
+ l = conn ? recv(s, &msg, sizeof(msg), 0) :
+ recvfrom(s, &msg, sizeof(msg), 0, (void *)&ss, &slen);
+ if (l == -1)
+ ERRX(EXIT_FAILURE, "recv (%s)", strerror(errno));
+ if (debug)
+ show("got", &msg);
+ if (seq != msg.seq)
+ ERRX(EXIT_FAILURE, "seq: expect=%zu actual=%zu",
+ seq, msg.seq);
+ }
+
+ /* Tell I'm finished */
+ synchronize(fd, false);
+}
+
+static void
+run(const char *host, const char *port, size_t n, bool conn, bool bug)
+{
+ pid_t pid;
+ int status;
+ int syncfds[2];
+ int error;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, syncfds) == -1)
+ ERRX(EXIT_FAILURE, "socketpair (%s)", strerror(errno));
+
+ switch ((pid = fork())) {
+ case 0:
+ receiver(syncfds[0], host, port, n, conn, bug);
+ return;
+ case -1:
+ ERRX(EXIT_FAILURE, "fork (%s)", strerror(errno));
+ default:
+ error = sender(syncfds[1], host, port, n, conn, bug);
+ again:
+ switch (waitpid(pid, &status, WNOHANG)) {
+ case -1:
+ ERRX(EXIT_FAILURE, "wait (%s)", strerror(errno));
+ case 0:
+ if (error == 0)
+ /*
+ * Receiver is still alive, but we know
+ * it will exit soon.
+ */
+ goto again;
+
+ if (kill(pid, SIGTERM) == -1)
+ ERRX(EXIT_FAILURE, "kill (%s)",
+ strerror(errno));
+ goto again;
+ default:
+ if (WIFSIGNALED(status)) {
+ if (WTERMSIG(status) == SIGTERM)
+ ERRX0(EXIT_FAILURE,
+ "receiver failed and was killed" \
+ "by sender");
+ else
+ ERRX(EXIT_FAILURE,
+ "receiver got signaled (%s)",
+ strsignal(WTERMSIG(status)));
+ } else if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0)
+ ERRX(EXIT_FAILURE,
+ "receiver exited with status %d",
+ WEXITSTATUS(status));
+ } else {
+ ERRX(EXIT_FAILURE,
+ "receiver exited with unexpected status %d",
+ status);
+ }
+ break;
+ }
+ return;
+ }
+}
+
+#ifndef ATF
+int
+main(int argc, char *argv[])
+{
+ const char *host, *port;
+ int c;
+ size_t n;
+ bool conn, bug;
+
+ host = HOST_V4;
+ port = PORT_V4;
+ n = TOTAL;
+ bug = conn = false;
+
+ while ((c = getopt(argc, argv, "46bcdmn:")) != -1)
+ switch (c) {
+ case '4':
+ host = HOST_V4;
+ port = PORT_V4;
+ break;
+ case '6':
+ host = HOST_V6;
+ port = PORT_V6;
+ break;
+ case 'b':
+ bug = true;
+ break;
+ case 'c':
+ conn = true;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'm':
+ host = HOST_V4MAPPED;
+ port = PORT_V4MAPPED;
+ break;
+ case 'n':
+ n = atoi(optarg);
+ break;
+ default:
+ fprintf(stderr, "Usage: %s [-cdm46] [-n <tot>]",
+ getprogname());
+ return 1;
+ }
+
+ run(host, port, n, conn, bug);
+ return 0;
+}
+#else
+
+ATF_TC(conninet4);
+ATF_TC_HEAD(conninet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv4");
+}
+
+ATF_TC_BODY(conninet4, tc)
+{
+ run(HOST_V4, PORT_V4, TOTAL, true, false);
+}
+
+ATF_TC(connmappedinet4);
+ATF_TC_HEAD(connmappedinet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks connected multicast for mapped ipv4");
+}
+
+ATF_TC_BODY(connmappedinet4, tc)
+{
+ run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, true, false);
+}
+
+ATF_TC(connmappedbuginet4);
+ATF_TC_HEAD(connmappedbuginet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks connected multicast for mapped ipv4 using the v4 ioctls");
+}
+
+ATF_TC_BODY(connmappedbuginet4, tc)
+{
+ run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, true, true);
+}
+
+ATF_TC(conninet6);
+ATF_TC_HEAD(conninet6, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks connected multicast for ipv6");
+}
+
+ATF_TC_BODY(conninet6, tc)
+{
+ run(HOST_V6, PORT_V6, TOTAL, true, false);
+}
+
+ATF_TC(unconninet4);
+ATF_TC_HEAD(unconninet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv4");
+}
+
+ATF_TC_BODY(unconninet4, tc)
+{
+ run(HOST_V4, PORT_V4, TOTAL, false, false);
+}
+
+ATF_TC(unconnmappedinet4);
+ATF_TC_HEAD(unconnmappedinet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for mapped ipv4");
+}
+
+ATF_TC_BODY(unconnmappedinet4, tc)
+{
+ run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, false, false);
+}
+
+ATF_TC(unconnmappedbuginet4);
+ATF_TC_HEAD(unconnmappedbuginet4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for mapped ipv4 using the v4 ioctls");
+}
+
+ATF_TC_BODY(unconnmappedbuginet4, tc)
+{
+ run(HOST_V4MAPPED, PORT_V4MAPPED, TOTAL, false, true);
+}
+
+ATF_TC(unconninet6);
+ATF_TC_HEAD(unconninet6, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks unconnected multicast for ipv6");
+}
+
+ATF_TC_BODY(unconninet6, tc)
+{
+ run(HOST_V6, PORT_V6, TOTAL, false, false);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ debug++;
+ ATF_TP_ADD_TC(tp, conninet4);
+ ATF_TP_ADD_TC(tp, connmappedinet4);
+ ATF_TP_ADD_TC(tp, connmappedbuginet4);
+ ATF_TP_ADD_TC(tp, conninet6);
+ ATF_TP_ADD_TC(tp, unconninet4);
+ ATF_TP_ADD_TC(tp, unconnmappedinet4);
+ ATF_TP_ADD_TC(tp, unconnmappedbuginet4);
+ ATF_TP_ADD_TC(tp, unconninet6);
+
+ return atf_no_error();
+}
+#endif
diff --git a/contrib/netbsd-tests/net/mcast/t_mcast.sh b/contrib/netbsd-tests/net/mcast/t_mcast.sh
new file mode 100755
index 0000000..aeb7000
--- /dev/null
+++ b/contrib/netbsd-tests/net/mcast/t_mcast.sh
@@ -0,0 +1,106 @@
+# $NetBSD: t_mcast.sh,v 1.4 2016/11/25 08:51:16 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+export RUMP_SERVER=unix://commsock
+
+DEBUG=${DEBUG:-false}
+
+run_test()
+{
+ local name="$1"
+ local opts="$2"
+ local mcast="$(atf_get_srcdir)/mcast"
+
+ rump_server_start $RUMP_SERVER netinet6
+ rump_server_add_iface $RUMP_SERVER shmif0 bus1
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.2/24
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fc00::2/64
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 rump.ifconfig -w 10
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep -q tentative"
+
+ # A route to the mcast address is required to join the mcast group
+ atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1
+ atf_check -s exit:0 -o ignore rump.route add -inet6 default fc00::1
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -nr
+
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ #$DEBUG && /usr/sbin/ifmcstat # Not yet run on rump kernel
+ if $DEBUG; then
+ atf_check -s exit:0 -o ignore $mcast -d ${opts}
+ else
+ atf_check -s exit:0 $mcast ${opts}
+ fi
+ #$DEBUG && /usr/sbin/ifmcstat # Not yet run on rump kernel
+ unset LD_PRELOAD
+}
+
+add_test()
+{
+ local name=$1
+ local opts="$2"
+ local desc="$3"
+
+ atf_test_case "mcast_${name}" cleanup
+ eval "mcast_${name}_head() { \
+ atf_set \"descr\" \"${desc}\"; \
+ atf_set \"require.progs\" \"rump_server\"; \
+ }; \
+ mcast_${name}_body() { \
+ run_test \"${name}\" \"${opts}\"; \
+ rump_server_destroy_ifaces; \
+ }; \
+ mcast_${name}_cleanup() { \
+ ${DEBUG} && dump; \
+ cleanup; \
+ }"
+ atf_add_test_case "mcast_${name}"
+}
+
+atf_init_test_cases()
+{
+
+ add_test conninet4 "-c -4" \
+ "Checks connected multicast for ipv4"
+ add_test connmappedinet4 "-c -m -4" \
+ "Checks connected multicast for mapped ipv4"
+ add_test connmappedbuginet4 "-c -m -b -4" \
+ "Checks connected multicast for mapped ipv4 using the v4 ioctls"
+ add_test conninet6 "-c -6" \
+ "Checks connected multicast for ipv6"
+ add_test unconninet4 "-4" \
+ "Checks unconnected multicast for ipv4"
+ add_test unconnmappedinet4 "-m -4" \
+ "Checks unconnected multicast for mapped ipv4"
+ add_test unconnmappedbuginet4 "-m -b -4" \
+ "Checks unconnected multicast for mapped ipv4 using the v4 ioctls"
+ add_test unconninet6 "-6" \
+ "Checks unconnected multicast for ipv6"
+}
diff --git a/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh b/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh
index 65fc29f..964b9ef 100755
--- a/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh
+++ b/contrib/netbsd-tests/net/mpls/t_ldp_regen.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_ldp_regen.sh,v 1.4 2014/09/01 06:38:35 gson Exp $
+# $NetBSD: t_ldp_regen.sh,v 1.7 2016/08/10 07:50:37 ozaki-r Exp $
#
# Copyright (c) 2013 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -41,7 +41,8 @@ RUMP_SERVER2=unix://./r2
RUMP_SERVER3=unix://./r3
RUMP_SERVER4=unix://./r4
-RUMP_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netmpls -lrumpnet_netinet -lrumpnet_netinet6 -lrumpnet_shmif"
+RUMP_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \
+ -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif"
LDP_FLAGS=""
atf_test_case ldp_regen cleanup
@@ -57,6 +58,8 @@ newaddr_and_ping() {
# Add new address on R4
RUMP_SERVER=${RUMP_SERVER4} atf_check -s exit:0 \
rump.ifconfig shmif1 10.0.5.1/24 alias
+ RUMP_SERVER=${RUMP_SERVER4} atf_check -s exit:0 \
+ rump.ifconfig -w 60
# Now ldpd on R5 should take notice of the new route and announce it
# to R4's ldpd. ldpd on R4 should verify that the next hop
@@ -145,6 +148,8 @@ create_servers() {
wait_ldp_ok() {
RUMP_SERVER=${RUMP_SERVER1} atf_check -s exit:0 -o ignore -e ignore \
+ rump.ifconfig -w 60
+ RUMP_SERVER=${RUMP_SERVER1} atf_check -s exit:0 -o ignore -e ignore \
rump.ping -o -w 60 10.0.4.1
}
@@ -158,7 +163,7 @@ docleanup() {
ldp_regen_body() {
- if sysctl machdep.cpu_brand | grep QEMU >/dev/null 2>&1
+ if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1
then
atf_skip "unreliable under qemu, skip until PR kern/43997 fixed"
fi
diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh
index ddd42df..f974b44 100755
--- a/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh
+++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_mpls_fw.sh,v 1.4 2014/03/18 18:20:44 riastradh Exp $
+# $NetBSD: t_mpls_fw.sh,v 1.5 2016/08/10 07:50:37 ozaki-r Exp $
#
# Copyright (c) 2013 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -42,8 +42,8 @@ RUMP_SERVER2=unix://./r2
RUMP_SERVER3=unix://./r3
RUMP_SERVER4=unix://./r4
-RUMP_FLAGS=\
-"-lrumpnet -lrumpnet_net -lrumpnet_netmpls -lrumpnet_netinet -lrumpnet_shmif"
+RUMP_FLAGS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \
+ -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif"
atf_test_case mplsfw4 cleanup
mplsfw4_head()
diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh
new file mode 100755
index 0000000..b9ac6cd
--- /dev/null
+++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw6.sh
@@ -0,0 +1,220 @@
+# $NetBSD: t_mpls_fw6.sh,v 1.3 2016/08/10 07:50:37 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+# Test MPLS encap/decap and forwarding using INET6 as encapsulated protocol
+# Setup four routers connected like this: R1---R2---R3---R4--
+# Goal is to be able to ping from R1 the outermost interface of R4
+# Disable net.inet6.ip6.forwarding, enable net.mpls.forwarding
+# Add route on R1 in order to encapsulate into MPLS the IP6 packets with
+# destination equal to R4 right hand side interface
+# Add MPLS routes on R2 in order to forward frames belonging to that FEC to R3
+# Add MPLS "POP" route on R3 for that FEC, pointing to R4
+# Do the same for the reverse direction (R4 to R1)
+# ping6 from R1 to R4 right hand side interface
+#
+# redo the test using IPv6 explicit null label
+
+RUMP_SERVER1=unix://./r1
+RUMP_SERVER2=unix://./r2
+RUMP_SERVER3=unix://./r3
+RUMP_SERVER4=unix://./r4
+
+RUMP_FLAGS6="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \
+ -lrumpdev -lrumpnet_shmif -lrumpnet_netmpls"
+
+atf_test_case mplsfw6 cleanup
+mplsfw6_head()
+{
+
+ atf_set "descr" "IP6/MPLS forwarding test using PHP"
+ atf_set "require.progs" "rump_server"
+}
+
+startservers()
+{
+
+ ulimit -r 300
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER1}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER2}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER3}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER4}
+}
+
+configservers()
+{
+
+ # Setup the first server
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -inet6 fd00:1234:0:3::/64 \
+ -ifa fd00:1234::1 \
+ -ifp mpls0 -tag 25 -inet6 fd00:1234::2
+
+ # Setup the second server
+ export RUMP_SERVER=${RUMP_SERVER2}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::2/64 alias
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:1::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30 \
+ -inet6 fd00:1234:0:1::2
+ atf_check -s exit:0 rump.route -q add -mpls 27 -tag ${1} -inet6 \
+ fd00:1234::1
+
+ # Setup the third server
+ export RUMP_SERVER=${RUMP_SERVER3}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:1::2/64 alias
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:2::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -mpls 30 -tag ${1} \
+ -inet6 fd00:1234:0:2::2
+ atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27 \
+ -inet6 fd00:1234:0:1::1
+
+ # Setup the fourth server
+ export RUMP_SERVER=${RUMP_SERVER4}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:2::2/64 alias
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:3::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -inet6 fd00:1234::/64 \
+ -ifa fd00:1234:0:2::2 \
+ -ifp mpls0 -tag 26 -inet6 fd00:1234:0:2::1
+
+ unset RUMP_SERVER
+}
+
+doping()
+{
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234::2, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234::2
+ export RUMP_SERVER=${RUMP_SERVER2}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234:0:1::2, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234:0:1::2
+ export RUMP_SERVER=${RUMP_SERVER3}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234:0:2::2, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234:0:2::2
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234:0:3::1, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234:0:3::1
+ unset RUMP_SERVER
+}
+
+do_check_route()
+{
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:"^fd00:1234:0:3::/64.+fd00:1234::2.+25.+mpls0" \
+ rump.netstat -nrT
+ unset RUMP_SERVER
+}
+
+docleanup()
+{
+
+ RUMP_SERVER=${RUMP_SERVER1} rump.halt
+ RUMP_SERVER=${RUMP_SERVER2} rump.halt
+ RUMP_SERVER=${RUMP_SERVER3} rump.halt
+ RUMP_SERVER=${RUMP_SERVER4} rump.halt
+}
+
+mplsfw6_body()
+{
+
+ startservers
+ configservers 3
+ do_check_route
+ doping
+}
+
+mplsfw6_cleanup()
+{
+
+ docleanup
+}
+
+
+atf_test_case mplsfw6_expl cleanup
+mplsfw4_expl_head()
+{
+
+ atf_set "descr" "IP6/MPLS forwarding test using explicit NULL labels"
+ atf_set "require.progs" "rump_server"
+}
+
+mplsfw6_expl_body()
+{
+
+ startservers
+ configservers 2
+ do_check_route
+ doping
+}
+
+mplsfw6_expl_cleanup()
+{
+
+ docleanup
+}
+
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case mplsfw6
+ atf_add_test_case mplsfw6_expl
+}
diff --git a/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh b/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh
new file mode 100755
index 0000000..9df3aa7
--- /dev/null
+++ b/contrib/netbsd-tests/net/mpls/t_mpls_fw64.sh
@@ -0,0 +1,226 @@
+# $NetBSD: t_mpls_fw64.sh,v 1.3 2016/08/10 07:50:37 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+# Test MPLS encap/decap and forwarding using INET6 as encapsulated protocol
+# Setup four routers connected like this: R1---R2---R3---R4--
+# Goal is to be able to ping from R1 the outermost interface of R4
+# Disable net.inet[6].ip[6].forwarding, enable net.mpls.forwarding
+# Use IPv6 between R1-R2-R3 and IPv4 between R3-R4
+# As we use IPv4 on last link we should use only expl.null there
+# because implicit null will assume IPv4 (as the next-hop)
+# But we can use impl null on R2-R1 link because stack will correctly
+# guess IPv6 (from next-hop)
+# Add route on R1 in order to encapsulate into MPLS the IP6 packets with
+# destination equal to R4 right hand side interface
+# Add MPLS routes on R2 in order to forward frames belonging to that FEC to R3
+# Add MPLS expl.null route on R3 for that FEC, pointing to R4
+# Do the same for the reverse direction (R4 to R1)
+# ping6 from R1 to R4 right hand side interface
+
+
+RUMP_SERVER1=unix://./r1
+RUMP_SERVER2=unix://./r2
+RUMP_SERVER3=unix://./r3
+RUMP_SERVER4=unix://./r4
+
+RUMP_FLAGS6="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_netinet6 \
+ -lrumpdev -lrumpnet_shmif -lrumpnet_netmpls"
+
+startservers()
+{
+
+ ulimit -r 300
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER1}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER2}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER3}
+ atf_check -s exit:0 rump_server ${RUMP_FLAGS6} ${RUMP_SERVER4}
+}
+
+configservers()
+{
+
+ # Setup the first server
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -inet6 fd00:1234:0:3::/64 \
+ -ifa fd00:1234::1 \
+ -ifp mpls0 -tag 25 -inet6 fd00:1234::2
+
+ # Setup the second server
+ export RUMP_SERVER=${RUMP_SERVER2}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234::2/64 alias
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom2
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:1::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.route -q add -mpls 25 -tag 30 \
+ -inet6 fd00:1234:0:1::2
+ atf_check -s exit:0 rump.route -q add -mpls 27 -tag ${1} -inet6 \
+ fd00:1234::1
+
+ # Setup the third server
+ export RUMP_SERVER=${RUMP_SERVER3}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom2
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 fd00:1234:0:1::2/64 alias
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom3
+ atf_check -s exit:0 rump.ifconfig shmif1 inet 10.0.3.1/24
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.forwarding=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0
+ atf_check -s exit:0 rump.route -q add -mpls 30 -tag 2 \
+ -inet 10.0.3.2
+ atf_check -s exit:0 rump.route -q add -mpls 26 -tag 27 \
+ -inet6 fd00:1234:0:1::1
+
+ # Setup the fourth server
+ export RUMP_SERVER=${RUMP_SERVER4}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ./shdom3
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.0.3.2
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ./shdom4
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 fd00:1234:0:3::1/64 alias
+ atf_check -s exit:0 rump.ifconfig mpls0 create up
+ atf_check -s exit:0 rump.sysctl -q -w net.mpls.accept=1
+ atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=0
+ atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=0
+ atf_check -s exit:0 rump.route -q add -inet6 fd00:1234::/64 \
+ -ifa fd00:1234:0:3::1 \
+ -ifp mpls0 -tag 26 -inet 10.0.3.1
+
+ unset RUMP_SERVER
+}
+
+doping()
+{
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234::2, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234::2
+ export RUMP_SERVER=${RUMP_SERVER2}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234:0:1::2, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234:0:1::2
+ export RUMP_SERVER=${RUMP_SERVER3}
+ atf_check -s exit:0 \
+ -o match:" bytes from 10.0.3.2: icmp_seq" \
+ rump.ping -n -o -w 2 10.0.3.2
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:" bytes from fd00:1234:0:3::1, icmp_seq=" \
+ rump.ping6 -n -o -X 2 fd00:1234:0:3::1
+ unset RUMP_SERVER
+}
+
+do_check_route()
+{
+
+ export RUMP_SERVER=${RUMP_SERVER1}
+ atf_check -s exit:0 \
+ -o match:"^fd00:1234:0:3::/64.+fd00:1234::2.+25.+mpls0" \
+ rump.netstat -nrT
+ unset RUMP_SERVER
+}
+
+docleanup()
+{
+
+ RUMP_SERVER=${RUMP_SERVER1} rump.halt
+ RUMP_SERVER=${RUMP_SERVER2} rump.halt
+ RUMP_SERVER=${RUMP_SERVER3} rump.halt
+ RUMP_SERVER=${RUMP_SERVER4} rump.halt
+}
+
+atf_test_case mplsfw64_impl cleanup
+mplsfw64_impl_head()
+{
+
+ atf_set "descr" "IP6/MPLS test using impl. NULL labels in mixed env."
+ atf_set "require.progs" "rump_server"
+}
+
+mplsfw64_impl_body()
+{
+
+ startservers
+ configservers 3
+ do_check_route
+ doping
+}
+
+mplsfw64_impl_cleanup()
+{
+
+ docleanup
+}
+
+
+atf_test_case mplsfw64_expl cleanup
+mplsfw64_expl_head()
+{
+
+ atf_set "descr" "IP6/MPLS test using explicit NULL labels in mixed env."
+ atf_set "require.progs" "rump_server"
+}
+
+mplsfw64_expl_body()
+{
+
+ startservers
+ configservers 2
+ do_check_route
+ doping
+}
+
+mplsfw64_expl_cleanup()
+{
+
+ docleanup
+}
+
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case mplsfw64_impl
+ atf_add_test_case mplsfw64_expl
+}
diff --git a/contrib/netbsd-tests/net/mpls/t_rfc4182.sh b/contrib/netbsd-tests/net/mpls/t_rfc4182.sh
index 8c166f9..558f7fd 100755
--- a/contrib/netbsd-tests/net/mpls/t_rfc4182.sh
+++ b/contrib/netbsd-tests/net/mpls/t_rfc4182.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_rfc4182.sh,v 1.3 2014/03/18 18:20:44 riastradh Exp $
+# $NetBSD: t_rfc4182.sh,v 1.4 2016/08/10 07:50:37 ozaki-r Exp $
#
# Copyright (c) 2013 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -44,8 +44,8 @@ RUMP_SERVER2=unix://./r2
RUMP_SERVER3=unix://./r3
RUMP_SERVER4=unix://./r4
-RUMP_FLAGS=\
-"-lrumpnet -lrumpnet_net -lrumpnet_netmpls -lrumpnet_netinet -lrumpnet_shmif"
+RUMP_FLAGS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \
+ -lrumpdev -lrumpnet_netmpls -lrumpnet_shmif"
atf_test_case rfc4182 cleanup
rfc4182_head()
diff --git a/contrib/netbsd-tests/net/ndp/t_dad.sh b/contrib/netbsd-tests/net/ndp/t_dad.sh
new file mode 100755
index 0000000..50ec933
--- /dev/null
+++ b/contrib/netbsd-tests/net/ndp/t_dad.sh
@@ -0,0 +1,276 @@
+# $NetBSD: t_dad.sh,v 1.12 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKLOCAL=unix://commsock1
+SOCKPEER=unix://commsock2
+
+DEBUG=${DEBUG:-false}
+
+duplicated="[Dd][Uu][Pp][Ll][Ii][Cc][Aa][Tt][Ee][Dd]"
+
+atf_test_case dad_basic cleanup
+atf_test_case dad_duplicated cleanup
+atf_test_case dad_count cleanup
+
+dad_basic_head()
+{
+ atf_set "descr" "Tests for IPv6 DAD basic behavior"
+ atf_set "require.progs" "rump_server"
+}
+
+dad_duplicated_head()
+{
+ atf_set "descr" "Tests for IPv6 DAD duplicated state"
+ atf_set "require.progs" "rump_server"
+}
+
+dad_count_head()
+{
+ atf_set "descr" "Tests for IPv6 DAD count behavior"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_server()
+{
+ local sock=$1
+ local ip=$2
+
+ rump_server_add_iface $sock shmif0 bus1
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig shmif0
+}
+
+make_ns_pkt_str()
+{
+ local id=$1
+ local target=$2
+ pkt="33:33:ff:00:00:0${id}, ethertype IPv6 (0x86dd), length 78: ::"
+ pkt="$pkt > ff02::1:ff00:${id}: ICMP6, neighbor solicitation,"
+ pkt="$pkt who has $target, length 24"
+ echo $pkt
+}
+
+dad_basic_body()
+{
+ local pkt=
+ local localip1=fc00::1
+ local localip2=fc00::2
+ local localip3=fc00::3
+
+ rump_server_start $SOCKLOCAL netinet6
+ rump_server_add_iface $SOCKLOCAL shmif0 bus1
+
+ export RUMP_SERVER=$SOCKLOCAL
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2
+ $DEBUG && rump.ifconfig shmif0
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ rump.ifconfig shmif0 > ./out
+ $DEBUG && cat ./out
+
+ # The primary address doesn't start with tentative state
+ atf_check -s not-exit:0 -x "cat ./out |grep $localip1 |grep -q tentative"
+ # The alias address starts with tentative state
+ # XXX we have no stable way to check this, so skip for now
+ #atf_check -s exit:0 -x "cat ./out |grep $localip2 |grep -q tentative"
+
+ atf_check -s exit:0 sleep 2
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # Check DAD probe packets (Neighbor Solicitation Message)
+ pkt=$(make_ns_pkt_str 2 $localip2)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+ # No DAD for the primary address
+ pkt=$(make_ns_pkt_str 1 $localip1)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ # Waiting for DAD complete
+ atf_check -s exit:0 rump.ifconfig -w 10
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # IPv6 DAD doesn't announce (Neighbor Advertisement Message)
+
+ # The alias address left tentative
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip2 |grep -q tentative"
+
+ #
+ # Add a new address on the fly
+ #
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip3
+
+ # The new address starts with tentative state
+ # XXX we have no stable way to check this, so skip for now
+ #atf_check -s exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative"
+
+ # Check DAD probe packets (Neighbor Solicitation Message)
+ atf_check -s exit:0 sleep 2
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+ pkt=$(make_ns_pkt_str 3 $localip3)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ # Waiting for DAD complete
+ atf_check -s exit:0 rump.ifconfig -w 10
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ # IPv6 DAD doesn't announce (Neighbor Advertisement Message)
+
+ # The new address left tentative
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif0 |grep $localip3 |grep -q tentative"
+
+ rump_server_destroy_ifaces
+}
+
+dad_duplicated_body()
+{
+ local localip1=fc00::1
+ local localip2=fc00::11
+ local peerip=fc00::2
+
+ rump_server_start $SOCKLOCAL netinet6
+ rump_server_start $SOCKPEER netinet6
+
+ setup_server $SOCKLOCAL $localip1
+ setup_server $SOCKPEER $peerip
+
+ export RUMP_SERVER=$SOCKLOCAL
+
+ # The primary address isn't marked as duplicated
+ atf_check -s exit:0 -o not-match:"$localip1.+$duplicated" \
+ rump.ifconfig shmif0
+
+ #
+ # Add a new address duplicated with the peer server
+ #
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $peerip
+ atf_check -s exit:0 sleep 1
+
+ # The new address is marked as duplicated
+ atf_check -s exit:0 -o match:"$peerip.+$duplicated" \
+ rump.ifconfig shmif0
+
+ # A unique address isn't marked as duplicated
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $localip2
+ atf_check -s exit:0 sleep 1
+ atf_check -s exit:0 -o not-match:"$localip2.+$duplicated" \
+ rump.ifconfig shmif0
+
+ rump_server_destroy_ifaces
+}
+
+dad_count_test()
+{
+ local pkt=
+ local count=$1
+ local id=$2
+ local target=$3
+
+ #
+ # Set DAD count to $count
+ #
+ atf_check -s exit:0 rump.sysctl -w -q net.inet6.ip6.dad_count=$count
+
+ # Add a new address
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $target
+
+ # Waiting for DAD complete
+ atf_check -s exit:0 rump.ifconfig -w 20
+
+ # Check the number of DAD probe packets (Neighbor Solicitation Message)
+ atf_check -s exit:0 sleep 2
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+ pkt=$(make_ns_pkt_str $id $target)
+ atf_check -s exit:0 -o match:"$count" \
+ -x "cat ./out |grep '$pkt' | wc -l | tr -d ' '"
+}
+
+dad_count_body()
+{
+ local localip1=fc00::1
+ local localip2=fc00::2
+
+ rump_server_start $SOCKLOCAL netinet6
+ rump_server_add_iface $SOCKLOCAL shmif0 bus1
+
+ export RUMP_SERVER=$SOCKLOCAL
+
+ # Check default value
+ atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet6.ip6.dad_count
+
+ # Setup interface
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 sleep 2
+ rump.ifconfig shmif0 > ./out
+ $DEBUG && cat ./out
+
+ #
+ # Set and test DAD count (count=1)
+ #
+ dad_count_test 1 1 $localip1
+
+ #
+ # Set and test DAD count (count=8)
+ #
+ dad_count_test 8 2 $localip2
+
+ rump_server_destroy_ifaces
+}
+
+dad_basic_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+dad_duplicated_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+dad_count_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case dad_basic
+ atf_add_test_case dad_duplicated
+ atf_add_test_case dad_count
+}
diff --git a/contrib/netbsd-tests/net/ndp/t_ndp.sh b/contrib/netbsd-tests/net/ndp/t_ndp.sh
new file mode 100755
index 0000000..aa96390
--- /dev/null
+++ b/contrib/netbsd-tests/net/ndp/t_ndp.sh
@@ -0,0 +1,406 @@
+# $NetBSD: t_ndp.sh,v 1.17 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKSRC=unix://commsock1
+SOCKDST=unix://commsock2
+IP6SRC=fc00::1
+IP6DST=fc00::2
+
+DEBUG=${DEBUG:-true}
+TIMEOUT=1
+
+atf_test_case ndp_cache_expiration cleanup
+atf_test_case ndp_commands cleanup
+atf_test_case ndp_cache_overwriting cleanup
+atf_test_case ndp_neighborgcthresh cleanup
+atf_test_case ndp_link_activation cleanup
+
+ndp_cache_expiration_head()
+{
+ atf_set "descr" "Tests for NDP cache expiration"
+ atf_set "require.progs" "rump_server"
+}
+
+ndp_commands_head()
+{
+ atf_set "descr" "Tests for commands of ndp(8)"
+ atf_set "require.progs" "rump_server"
+}
+
+ndp_cache_overwriting_head()
+{
+ atf_set "descr" "Tests for behavior of overwriting NDP caches"
+ atf_set "require.progs" "rump_server"
+}
+
+ndp_neighborgcthresh_head()
+{
+ atf_set "descr" "Tests for GC of neighbor caches"
+ atf_set "require.progs" "rump_server"
+}
+
+ndp_link_activation_head()
+{
+ atf_set "descr" "Tests for activating a new MAC address"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_dst_server()
+{
+ local assign_ip=$1
+
+ rump_server_add_iface $SOCKDST shmif0 bus1
+ export RUMP_SERVER=$SOCKDST
+ if [ "$assign_ip" != no ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6DST
+ fi
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig shmif0
+ $DEBUG && rump.ndp -n -a
+}
+
+setup_src_server()
+{
+ $DEBUG && ulimit -c unlimited
+ export RUMP_SERVER=$SOCKSRC
+
+ # Setup an interface
+ rump_server_add_iface $SOCKSRC shmif0 bus1
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ # Sanity check
+ $DEBUG && rump.ifconfig shmif0
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o ignore rump.ndp -n $IP6SRC
+ atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
+}
+
+get_timeout()
+{
+ local timeout=$(env RUMP_SERVER=$SOCKSRC rump.ndp -n $IP6DST |grep $IP6DST|awk '{print $4;}')
+ timeout=${timeout%s}
+ echo $timeout
+}
+
+ndp_cache_expiration_body()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server
+ setup_src_server
+
+ #
+ # Check if a cache is expired expectedly
+ #
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
+
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
+ # Should be cached
+ atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
+
+ timeout=$(get_timeout $IP6DST)
+
+ atf_check -s exit:0 sleep $(($timeout + 1))
+
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6SRC
+ # Expired but remains until GC sweaps it (1 day)
+ atf_check -s exit:0 -o match:'(1d0h0m|23h59m)' rump.ndp -n $IP6DST
+
+ rump_server_destroy_ifaces
+}
+
+ifdown_dst_server()
+{
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 rump.ifconfig shmif0 down
+ export RUMP_SERVER=$SOCKSRC
+}
+
+ndp_commands_body()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server
+ setup_src_server
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # We can delete the entry for the interface's IP address
+ atf_check -s exit:0 -o match:"$IP6SRC" rump.ndp -d $IP6SRC
+
+ # Add and delete a static entry
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::10
+ atf_check -s exit:0 -o match:'deleted' rump.ndp -d fc00::10
+ $DEBUG && rump.ndp -n -a
+ atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n fc00::10
+
+ # Add multiple entries via a file (XXX not implemented)
+ #cat - > ./list <<-EOF
+ #fc00::11 b2:a0:20:00:00:11
+ #fc00::12 b2:a0:20:00:00:12
+ #fc00::13 b2:a0:20:00:00:13
+ #fc00::14 b2:a0:20:00:00:14
+ #fc00::15 b2:a0:20:00:00:15
+ #EOF
+ #$DEBUG && rump.ndp -n -a
+ #atf_check -s exit:0 -o ignore rump.ndp -f ./list
+ #$DEBUG && rump.ndp -n -a
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
+ atf_check -s exit:0 -o ignore rump.ndp -s fc00::11 b2:a0:20:00:00:11
+ atf_check -s exit:0 -o ignore rump.ndp -s fc00::12 b2:a0:20:00:00:12
+
+ atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n $IP6DST
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::11
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n fc00::12
+
+ # Test ndp -a
+ atf_check -s exit:0 -o match:'fc00::11' rump.ndp -n -a
+ atf_check -s exit:0 -o match:'fc00::12' rump.ndp -n -a
+
+ # Ensure no packet upsets the src server
+ ifdown_dst_server
+
+ # Flush all entries (-c)
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o ignore rump.ndp -c
+ atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6SRC
+ atf_check -s not-exit:0 -o ignore -e ignore rump.ndp -n $IP6DST
+ # Only the static caches are not deleted
+ atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::11
+ atf_check -s exit:0 -o ignore -e ignore rump.ndp -n fc00::12
+
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
+ rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
+
+ rump_server_destroy_ifaces
+}
+
+ndp_cache_overwriting_body()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server
+ setup_src_server
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # Cannot overwrite a permanent cache
+ atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
+ $DEBUG && rump.ndp -n -a
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
+ $DEBUG && rump.ndp -n -a
+ # Can overwrite a dynamic cache
+ atf_check -s exit:0 -o ignore rump.ndp -s $IP6DST b2:a0:20:00:00:00
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'permanent' rump.ndp -n $IP6DST
+
+ # Test temp option (XXX it doesn't work; expire time isn't set)
+ #atf_check -s exit:0 -o ignore rump.ndp -s fc00::10 b2:a0:20:00:00:10 temp
+ #$DEBUG && rump.ndp -n -a
+ #atf_check -s exit:0 -o not-match:'permanent' rump.ndp -n fc00::10
+ # Cannot overwrite a temp cache
+ #atf_check -s not-exit:0 -e ignore rump.ndp -s fc00::10 b2:a0:20:00:00:ff
+ #$DEBUG && rump.ndp -n -a
+
+ rump_server_destroy_ifaces
+}
+
+get_n_caches()
+{
+
+ echo $(rump.ndp -a -n |grep -v -e Neighbor -e permanent |wc -l)
+}
+
+ndp_neighborgcthresh_body()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server no
+ setup_src_server
+
+ export RUMP_SERVER=$SOCKDST
+ for i in $(seq 0 9); do
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6DST}$i
+ done
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # ping to 3 destinations
+ $DEBUG && rump.ndp -n -a
+ for i in $(seq 0 2); do
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
+ ${IP6DST}$i
+ done
+ $DEBUG && rump.ndp -n -a
+
+ # 3 caches should be created
+ atf_check_equal $(get_n_caches) 3
+
+ # ping to additional 3 destinations
+ for i in $(seq 3 5); do
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
+ ${IP6DST}$i
+ done
+ $DEBUG && rump.ndp -n -a
+
+ # 6 caches should be created in total
+ atf_check_equal $(get_n_caches) 6
+
+ # Limit the number of neighbor caches to 5
+ atf_check -s exit:0 -o ignore rump.sysctl -w \
+ net.inet6.ip6.neighborgcthresh=5
+
+ # ping to additional 4 destinations
+ for i in $(seq 6 9); do
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 \
+ ${IP6DST}$i
+ done
+
+ # More than 5 caches should be created in total, but exceeded caches
+ # should be GC-ed
+ if [ "$(get_n_caches)" -gt 5 ]; then
+ atf_fail "Neighbor caches are not GC-ed"
+ fi
+
+ rump_server_destroy_ifaces
+}
+
+make_pkt_str_na()
+{
+ local ip=$1
+ local mac=$2
+ local pkt=
+ pkt="$mac > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86:"
+ pkt="$pkt $ip > ff02::1: ICMP6, neighbor advertisement"
+ echo $pkt
+}
+
+ndp_link_activation_body()
+{
+ local linklocal=
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server
+ setup_src_server
+
+ # flush old packets
+ extract_new_packets bus1 > ./out
+
+ export RUMP_SERVER=$SOCKSRC
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
+ b2:a1:00:00:00:01
+
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
+ $DEBUG && echo $linklocal
+
+ pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:01)
+ atf_check -s not-exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 link \
+ b2:a1:00:00:00:02 active
+
+ atf_check -s exit:0 sleep 1
+ extract_new_packets bus1 > ./out
+ $DEBUG && cat ./out
+
+ linklocal=$(rump.ifconfig shmif0 |awk '/fe80/ {print $2;}' |awk -F % '{print $1;}')
+ $DEBUG && echo $linklocal
+
+ pkt=$(make_pkt_str_na $linklocal b2:a1:00:00:00:02)
+ atf_check -s exit:0 -x "cat ./out |grep -q '$pkt'"
+
+ rump_server_destroy_ifaces
+}
+
+ndp_cache_expiration_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ndp_commands_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ndp_cache_overwriting_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ndp_neighborgcthresh_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ndp_link_activation_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case ndp_cache_expiration
+ atf_add_test_case ndp_commands
+ atf_add_test_case ndp_cache_overwriting
+ atf_add_test_case ndp_neighborgcthresh
+ atf_add_test_case ndp_link_activation
+}
diff --git a/contrib/netbsd-tests/net/ndp/t_ra.sh b/contrib/netbsd-tests/net/ndp/t_ra.sh
new file mode 100755
index 0000000..b234570
--- /dev/null
+++ b/contrib/netbsd-tests/net/ndp/t_ra.sh
@@ -0,0 +1,687 @@
+# $NetBSD: t_ra.sh,v 1.20 2017/01/11 03:15:44 ozaki-r Exp $
+#
+# Copyright (c) 2015 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+RUMPSRV=unix://r1
+RUMPSRV1_2=unix://r12
+RUMPCLI=unix://r2
+RUMPSRV3=unix://r3
+RUMPSRV4=unix://r4
+IP6SRV=fc00:1::1
+IP6SRV1_2=fc00:1::2
+IP6SRV_PREFIX=fc00:1:
+IP6CLI=fc00:2::2
+IP6SRV3=fc00:3::1
+IP6SRV3_PREFIX=fc00:3:
+IP6SRV4=fc00:4::1
+IP6SRV4_PREFIX=fc00:4:
+PIDFILE=./rump.rtadvd.pid
+PIDFILE1_2=./rump.rtadvd.pid12
+PIDFILE3=./rump.rtadvd.pid3
+PIDFILE4=./rump.rtadvd.pid4
+CONFIG=./rtadvd.conf
+WAITTIME=2
+DEBUG=${DEBUG:-true}
+
+init_server()
+{
+
+ export RUMP_SERVER=$1
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.forwarding=1
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ atf_check -s exit:0 mkdir -p /rump/var/chroot/rtadvd
+ unset LD_PRELOAD
+ unset RUMP_SERVER
+}
+
+setup_shmif0()
+{
+ local sock=$1
+ local IP6ADDR=$2
+
+ rump_server_add_iface $sock shmif0 bus1
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6ADDR}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig
+}
+
+wait_term()
+{
+ local PIDFILE=${1}
+ shift
+
+ while [ -f ${PIDFILE} ]
+ do
+ sleep 0.2
+ done
+
+ return 0
+}
+
+create_rtadvdconfig()
+{
+
+ cat << _EOF > ${CONFIG}
+shmif0:\
+ :mtu#1300:maxinterval#4:mininterval#3:
+_EOF
+}
+
+start_rtadvd()
+{
+ local sock=$1
+ local pidfile=$2
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.rtadvd -c ${CONFIG} -p $pidfile shmif0
+ while [ ! -f $pidfile ]; do
+ sleep 0.2
+ done
+ unset RUMP_SERVER
+}
+
+check_entries()
+{
+ local cli=$1
+ local srv=$2
+ local addr_prefix=$3
+ local mac_srv= ll_srv=
+
+ ll_srv=$(get_linklocal_addr $srv shmif0)
+ mac_srv=$(get_macaddr $srv shmif0)
+
+ export RUMP_SERVER=$cli
+ $DEBUG && dump_entries
+ atf_check -s exit:0 -o match:'if=shmif0' rump.ndp -r
+ atf_check -s exit:0 -o match:'advertised' rump.ndp -p
+ atf_check -s exit:0 -o match:"${ll_srv}%shmif0 \(reachable\)" rump.ndp -p
+ atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0
+ atf_check -s exit:0 \
+ -o match:"$ll_srv%shmif0 +$mac_srv +shmif0 +(23h59m|1d0h0m)..s S R" \
+ rump.ndp -n -a
+ atf_check -s exit:0 -o match:$addr_prefix rump.ndp -n -a
+ atf_check -s exit:0 -o match:"$addr_prefix.+<AUTOCONF>" \
+ rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+}
+
+dump_entries()
+{
+
+ echo ndp -n -a
+ rump.ndp -n -a
+ echo ndp -p
+ rump.ndp -p
+ echo ndp -r
+ rump.ndp -r
+}
+
+atf_test_case ra_basic cleanup
+ra_basic_head()
+{
+
+ atf_set "descr" "Tests for basic functions of router advaertisement(RA)"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_basic_body()
+{
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ init_server $RUMPSRV
+
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+ export RUMP_SERVER=${RUMPCLI}
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'= 0' rump.sysctl net.inet6.ip6.accept_rtadv
+ unset RUMP_SERVER
+
+ create_rtadvdconfig
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o empty rump.ndp -r
+ atf_check -s exit:0 -o not-match:'advertised' rump.ndp -p
+ atf_check -s exit:0 -o match:'linkmtu=0' rump.ndp -n -i shmif0
+ atf_check -s exit:0 -o not-match:'S R' rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'fc00:1:' rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+
+ rump_server_destroy_ifaces
+}
+
+ra_basic_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_flush_prefix_entries cleanup
+ra_flush_prefix_entries_head()
+{
+
+ atf_set "descr" "Tests for flushing prefixes (ndp -P)"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_flush_prefix_entries_body()
+{
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+
+ export RUMP_SERVER=${RUMPCLI}
+
+ # Terminate rtadvd to prevent new RA messages from coming
+ # Note that ifconfig down; kill -TERM doesn't work
+ kill -KILL `cat ${PIDFILE}`
+
+ # Flush all the entries in the prefix list
+ atf_check -s exit:0 rump.ndp -P
+
+ $DEBUG && dump_entries
+ atf_check -s exit:0 -o match:'if=shmif0' rump.ndp -r
+ atf_check -s exit:0 -o empty rump.ndp -p
+ atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0
+ atf_check -s exit:0 -o match:'(23h59m|1d0h0m)..s S R' rump.ndp -n -a
+ atf_check -s exit:0 -o match:'fc00:1:' rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+
+ rump_server_destroy_ifaces
+}
+
+ra_flush_prefix_entries_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_flush_defrouter_entries cleanup
+ra_flush_defrouter_entries_head()
+{
+
+ atf_set "descr" "Tests for flushing default routers (ndp -R)"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_flush_defrouter_entries_body()
+{
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+
+ export RUMP_SERVER=${RUMPCLI}
+
+ # Terminate rtadvd to prevent new RA messages from coming
+ # Note that ifconfig down; kill -TERM doesn't work
+ kill -KILL `cat ${PIDFILE}`
+
+ # Flush all the entries in the default router list
+ atf_check -s exit:0 rump.ndp -R
+
+ $DEBUG && dump_entries
+ atf_check -s exit:0 -o empty rump.ndp -r
+ atf_check -s exit:0 -o match:'No advertising router' rump.ndp -p
+ atf_check -s exit:0 -o match:'linkmtu=1300' rump.ndp -n -i shmif0
+ atf_check -s exit:0 -o match:'(23h59m|1d0h0m)..s S R' rump.ndp -n -a
+ atf_check -s exit:0 -o match:'fc00:1:' rump.ndp -n -a
+ atf_check -s exit:0 -o match:'fc00:1:' rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+
+ rump_server_destroy_ifaces
+}
+
+ra_flush_defrouter_entries_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_delete_address cleanup
+ra_delete_address_head()
+{
+
+ atf_set "descr" "Tests for deleting auto-configured address"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_delete_address_body()
+{
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+
+ export RUMP_SERVER=${RUMPCLI}
+ $DEBUG && rump.ifconfig shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 \
+ $(rump.ifconfig shmif0 |awk '/AUTOCONF/ {print $2}') delete
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+
+ rump_server_destroy_ifaces
+}
+
+ra_delete_address_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_multiple_routers cleanup
+ra_multiple_routers_head()
+{
+
+ atf_set "descr" "Tests for multiple routers"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_multiple_routers_body()
+{
+ local n=
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_fs_start $RUMPSRV3 netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPSRV3} ${IP6SRV3}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+ init_server $RUMPSRV3
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ start_rtadvd $RUMPSRV3 $PIDFILE3
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+ check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX
+
+ export RUMP_SERVER=$RUMPCLI
+ # Two prefixes are advertised by differnt two routers
+ n=$(rump.ndp -p |grep 'advertised by' |wc -l)
+ atf_check_equal $n 2
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE3}`
+ wait_term ${PIDFILE3}
+
+ rump_server_destroy_ifaces
+}
+
+ra_multiple_routers_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+ if [ -f ${PIDFILE3} ]; then
+ kill -TERM `cat ${PIDFILE3}`
+ wait_term ${PIDFILE3}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_multiple_routers_single_prefix cleanup
+ra_multiple_routers_single_prefix_head()
+{
+
+ atf_set "descr" "Tests for multiple routers with a single prefix"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_multiple_routers_single_prefix_body()
+{
+ local n=
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_fs_start $RUMPSRV1_2 netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPSRV1_2} ${IP6SRV1_2}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+ init_server $RUMPSRV1_2
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ start_rtadvd $RUMPSRV1_2 $PIDFILE1_2
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+ check_entries $RUMPCLI $RUMPSRV1_2 $IP6SRV_PREFIX
+
+ export RUMP_SERVER=$RUMPCLI
+ # One prefix is advertised by differnt two routers
+ n=$(rump.ndp -p |grep 'advertised by' |wc -l)
+ atf_check_equal $n 1
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE1_2}`
+ wait_term ${PIDFILE1_2}
+
+ rump_server_destroy_ifaces
+}
+
+ra_multiple_routers_single_prefix_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+ if [ -f ${PIDFILE1_2} ]; then
+ kill -TERM `cat ${PIDFILE1_2}`
+ wait_term ${PIDFILE1_2}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_multiple_routers_maxifprefixes cleanup
+ra_multiple_routers_maxifprefixes_head()
+{
+
+ atf_set "descr" "Tests for exceeding the number of maximum prefixes"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_multiple_routers_maxifprefixes_body()
+{
+ local n=
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_fs_start $RUMPSRV3 netinet6
+ rump_server_fs_start $RUMPSRV4 netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ setup_shmif0 ${RUMPSRV3} ${IP6SRV3}
+ setup_shmif0 ${RUMPSRV4} ${IP6SRV4}
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+
+ init_server $RUMPSRV
+ init_server $RUMPSRV3
+ init_server $RUMPSRV4
+
+ create_rtadvdconfig
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' \
+ rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ # Limit the maximum number of prefix entries to 2
+ atf_check -s exit:0 -o match:'16.->.2' \
+ rump.sysctl -w net.inet6.ip6.maxifprefixes=2
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ start_rtadvd $RUMPSRV3 $PIDFILE3
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+ check_entries $RUMPCLI $RUMPSRV3 $IP6SRV3_PREFIX
+
+ start_rtadvd $RUMPSRV4 $PIDFILE4
+ sleep $WAITTIME
+
+ export RUMP_SERVER=${RUMPCLI}
+ $DEBUG && dump_entries
+ # There should remain two prefixes
+ n=$(rump.ndp -p |grep 'advertised by' |wc -l)
+ atf_check_equal $n 2
+ # TODO check other conditions
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE3}`
+ wait_term ${PIDFILE3}
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE4}`
+ wait_term ${PIDFILE4}
+
+ rump_server_destroy_ifaces
+}
+
+ra_multiple_routers_maxifprefixes_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+ if [ -f ${PIDFILE3} ]; then
+ kill -TERM `cat ${PIDFILE3}`
+ wait_term ${PIDFILE3}
+ fi
+ if [ -f ${PIDFILE4} ]; then
+ kill -TERM `cat ${PIDFILE4}`
+ wait_term ${PIDFILE4}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ra_temporary_address cleanup
+ra_temporary_address_head()
+{
+
+ atf_set "descr" "Tests for IPv6 temporary address"
+ atf_set "require.progs" "rump_server rump.rtadvd rump.ndp rump.ifconfig"
+}
+
+ra_temporary_address_body()
+{
+
+ rump_server_fs_start $RUMPSRV netinet6
+ rump_server_start $RUMPCLI netinet6
+
+ setup_shmif0 ${RUMPSRV} ${IP6SRV}
+ init_server $RUMPSRV
+
+ setup_shmif0 ${RUMPCLI} ${IP6CLI}
+ export RUMP_SERVER=${RUMPCLI}
+ $DEBUG && rump.ndp -n -a
+ atf_check -s exit:0 -o match:'= 0' \
+ rump.sysctl net.inet6.ip6.accept_rtadv
+ atf_check -s exit:0 -o match:'= 0' \
+ rump.sysctl net.inet6.ip6.use_tempaddr
+ unset RUMP_SERVER
+
+ create_rtadvdconfig
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o empty rump.ndp -r
+ atf_check -s exit:0 -o not-match:'advertised' rump.ndp -p
+ atf_check -s exit:0 -o match:'linkmtu=0' rump.ndp -n -i shmif0
+ atf_check -s exit:0 -o not-match:'S R' rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'fc00:1:' rump.ndp -n -a
+ atf_check -s exit:0 -o not-match:'fc00:1:' rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:'0.->.1' \
+ rump.sysctl -w net.inet6.ip6.accept_rtadv=1
+ atf_check -s exit:0 -o match:'0.->.1' \
+ rump.sysctl -w net.inet6.ip6.use_tempaddr=1
+ unset RUMP_SERVER
+
+ start_rtadvd $RUMPSRV $PIDFILE
+ sleep $WAITTIME
+
+ check_entries $RUMPCLI $RUMPSRV $IP6SRV_PREFIX
+
+ # Check temporary address
+ export RUMP_SERVER=${RUMPCLI}
+ atf_check -s exit:0 -o match:"$IP6SRV_PREFIX.+<AUTOCONF,TEMPORARY>" \
+ rump.ifconfig shmif0 inet6
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+
+ rump_server_destroy_ifaces
+}
+
+ra_temporary_address_cleanup()
+{
+
+ if [ -f ${PIDFILE} ]; then
+ kill -TERM `cat ${PIDFILE}`
+ wait_term ${PIDFILE}
+ fi
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case ra_basic
+ atf_add_test_case ra_flush_prefix_entries
+ atf_add_test_case ra_flush_defrouter_entries
+ atf_add_test_case ra_delete_address
+ atf_add_test_case ra_multiple_routers
+ atf_add_test_case ra_multiple_routers_single_prefix
+ atf_add_test_case ra_multiple_routers_maxifprefixes
+ atf_add_test_case ra_temporary_address
+}
diff --git a/contrib/netbsd-tests/net/net/t_forwarding.sh b/contrib/netbsd-tests/net/net/t_forwarding.sh
new file mode 100755
index 0000000..fc30530
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_forwarding.sh
@@ -0,0 +1,530 @@
+# $NetBSD: t_forwarding.sh,v 1.19 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKSRC=unix://commsock1
+SOCKFWD=unix://commsock2
+SOCKDST=unix://commsock3
+IP4SRC=10.0.1.2
+IP4SRCGW=10.0.1.1
+IP4DSTGW=10.0.2.1
+IP4DST=10.0.2.2
+IP4DST_BCAST=10.0.2.255
+IP6SRC=fc00:0:0:1::2
+IP6SRCGW=fc00:0:0:1::1
+IP6DSTGW=fc00:0:0:2::1
+IP6DST=fc00:0:0:2::2
+HTML_FILE=index.html
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=5
+
+atf_test_case ipforwarding_v4 cleanup
+atf_test_case ipforwarding_v6 cleanup
+atf_test_case ipforwarding_fastforward_v4 cleanup
+atf_test_case ipforwarding_fastforward_v6 cleanup
+atf_test_case ipforwarding_misc cleanup
+
+ipforwarding_v4_head()
+{
+ atf_set "descr" "Does IPv4 forwarding tests"
+ atf_set "require.progs" "rump_server"
+}
+
+ipforwarding_v6_head()
+{
+ atf_set "descr" "Does IPv6 forwarding tests"
+ atf_set "require.progs" "rump_server"
+}
+
+ipforwarding_fastforward_v4_head()
+{
+ atf_set "descr" "Tests for IPv4 fastforward"
+ atf_set "require.progs" "rump_server"
+}
+
+ipforwarding_fastforward_v6_head()
+{
+ atf_set "descr" "Tests for IPv6 fastfoward"
+ atf_set "require.progs" "rump_server"
+}
+
+ipforwarding_misc_head()
+{
+ atf_set "descr" "Does IPv4 forwarding tests"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_endpoint()
+{
+ sock=${1}
+ addr=${2}
+ bus=${3}
+ mode=${4}
+ gw=${5}
+
+ rump_server_add_iface $sock shmif0 $bus
+
+ export RUMP_SERVER=${sock}
+ if [ $mode = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr}
+ atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00
+ atf_check -s exit:0 -o ignore rump.route add default ${gw}
+ fi
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ if $DEBUG; then
+ rump.ifconfig shmif0
+ rump.netstat -nr
+ fi
+}
+
+test_endpoint()
+{
+ sock=${1}
+ addr=${2}
+ bus=${3}
+ mode=${4}
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 -o match:shmif0 rump.ifconfig
+ if [ $mode = "ipv6" ]; then
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr}
+ else
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr}
+ fi
+}
+
+setup_forwarder()
+{
+ mode=${1}
+
+ rump_server_add_iface $SOCKFWD shmif0 bus1
+ rump_server_add_iface $SOCKFWD shmif1 bus2
+
+ export RUMP_SERVER=$SOCKFWD
+
+ if [ $mode = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW}
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif0 inet ${IP4SRCGW} netmask 0xffffff00
+ atf_check -s exit:0 rump.ifconfig shmif1 inet ${IP4DSTGW} netmask 0xffffff00
+ fi
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+
+ if $DEBUG; then
+ rump.netstat -nr
+ if [ $mode = "ipv6" ]; then
+ rump.sysctl net.inet6.ip6.forwarding
+ else
+ rump.sysctl net.inet.ip.forwarding
+ fi
+ fi
+}
+
+setup()
+{
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKFWD
+ rump_server_start $SOCKDST
+
+ setup_endpoint $SOCKSRC $IP4SRC bus1 ipv4 $IP4SRCGW
+ setup_endpoint $SOCKDST $IP4DST bus2 ipv4 $IP4DSTGW
+ setup_forwarder ipv4
+}
+
+setup6()
+{
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKFWD netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_endpoint $SOCKSRC $IP6SRC bus1 ipv6 $IP6SRCGW
+ setup_endpoint $SOCKDST $IP6DST bus2 ipv6 $IP6DSTGW
+ setup_forwarder ipv6
+}
+
+test_http_get()
+{
+ local ip=$1
+
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 rump.arp -d -a
+
+ export RUMP_SERVER=$SOCKSRC
+
+ # get the webpage
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE
+}
+
+test_setup()
+{
+ test_endpoint $SOCKSRC $IP4SRC bus1 ipv4
+ test_endpoint $SOCKDST $IP4DST bus2 ipv4
+
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:shmif0 rump.ifconfig
+ atf_check -s exit:0 -o match:shmif1 rump.ifconfig
+
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${IP4SRCGW}
+ atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${IP4DSTGW}
+}
+
+test_setup6()
+{
+ test_endpoint $SOCKSRC $IP6SRC bus1 ipv6
+ test_endpoint $SOCKDST $IP6DST bus2 ipv6
+
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:shmif0 rump.ifconfig
+ atf_check -s exit:0 -o match:shmif1 rump.ifconfig
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${IP6SRCGW}
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${IP6DSTGW}
+}
+
+setup_forwarding()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1
+}
+
+setup_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1
+}
+
+setup_directed_broadcast()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.directed-broadcast=1
+}
+
+setup_icmp_bmcastecho()
+{
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.icmp.bmcastecho=1
+}
+
+teardown_forwarding()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=0
+}
+
+teardown_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=0
+}
+
+teardown_directed_broadcast()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.directed-broadcast=0
+}
+
+teardown_icmp_bmcastecho()
+{
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.icmp.bmcastecho=0
+}
+
+teardown_interfaces()
+{
+
+ rump_server_destroy_ifaces
+}
+
+test_setup_forwarding()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:"net.inet.ip.forwarding = 1" \
+ rump.sysctl net.inet.ip.forwarding
+}
+test_setup_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:"net.inet6.ip6.forwarding = 1" \
+ rump.sysctl net.inet6.ip6.forwarding
+}
+
+test_teardown_forwarding()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:"net.inet.ip.forwarding = 0" \
+ rump.sysctl net.inet.ip.forwarding
+}
+test_teardown_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o match:"net.inet6.ip6.forwarding = 0" \
+ rump.sysctl net.inet6.ip6.forwarding
+}
+
+test_ping_failure()
+{
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRC
+}
+
+test_ping_success()
+{
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRCGW
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST
+ $DEBUG && rump.ifconfig -v shmif0
+
+ export RUMP_SERVER=$SOCKDST
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DSTGW
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRC
+ $DEBUG && rump.ifconfig -v shmif0
+}
+
+test_ping_ttl()
+{
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 -T 1 $IP4SRCGW
+ atf_check -s not-exit:0 -o match:'Time To Live exceeded' \
+ rump.ping -v -n -w $TIMEOUT -c 1 -T 1 $IP4DST
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 -T 2 $IP4DST
+ $DEBUG && rump.ifconfig -v shmif0
+}
+
+test_sysctl_ttl()
+{
+ local ip=$1
+
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.ifconfig -v shmif0
+
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=1
+ # get the webpage
+ atf_check -s not-exit:0 -e match:'timed out' \
+ env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE
+
+
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=2
+ # get the webpage
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ftp -q $TIMEOUT -o out http://$ip/$HTML_FILE
+
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.ttl=64
+ $DEBUG && rump.ifconfig -v shmif0
+}
+
+test_directed_broadcast()
+{
+ setup_icmp_bmcastecho
+
+ setup_directed_broadcast
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST_BCAST
+
+ teardown_directed_broadcast
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4DST_BCAST
+
+ teardown_icmp_bmcastecho
+}
+
+test_ping6_failure()
+{
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DST
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRC
+}
+
+test_ping6_success()
+{
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRCGW
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DST
+ $DEBUG && rump.ifconfig -v shmif0
+
+ export RUMP_SERVER=$SOCKDST
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6DSTGW
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP6SRC
+ $DEBUG && rump.ifconfig -v shmif0
+}
+
+test_hoplimit()
+{
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.ifconfig -v shmif0
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -h 1 -X $TIMEOUT $IP6SRCGW
+ atf_check -s not-exit:0 -o match:'Time to live exceeded' \
+ rump.ping6 -v -n -c 1 -h 1 -X $TIMEOUT $IP6DST
+ atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -h 2 -X $TIMEOUT $IP6DST
+ $DEBUG && rump.ifconfig -v shmif0
+}
+
+ipforwarding_v4_body()
+{
+ setup
+ test_setup
+
+ setup_forwarding
+ test_setup_forwarding
+ test_ping_success
+
+ teardown_forwarding
+ test_teardown_forwarding
+ test_ping_failure
+
+ teardown_interfaces
+}
+
+ipforwarding_v6_body()
+{
+ setup6
+ test_setup6
+
+ setup_forwarding6
+ test_setup_forwarding6
+ test_ping6_success
+ test_hoplimit
+
+ teardown_forwarding6
+ test_teardown_forwarding6
+ test_ping6_failure
+
+ teardown_interfaces
+}
+
+ipforwarding_fastforward_v4_body()
+{
+ setup
+ test_setup
+
+ setup_forwarding
+ test_setup_forwarding
+
+ touch $HTML_FILE
+ start_httpd $SOCKDST $IP4DST
+ $DEBUG && rump.netstat -a
+
+ test_http_get $IP4DST
+
+ teardown_interfaces
+}
+
+ipforwarding_fastforward_v6_body()
+{
+ setup6
+ test_setup6
+
+ setup_forwarding6
+ test_setup_forwarding6
+
+ touch $HTML_FILE
+ start_httpd $SOCKDST $IP6DST
+ $DEBUG && rump.netstat -a
+
+ test_http_get "[$IP6DST]"
+
+ teardown_interfaces
+}
+
+ipforwarding_misc_body()
+{
+ setup
+ test_setup
+
+ setup_forwarding
+ test_setup_forwarding
+
+ test_ping_ttl
+
+ test_directed_broadcast
+
+ touch $HTML_FILE
+ start_httpd $SOCKDST $IP4DST
+ $DEBUG && rump.netstat -a
+
+ test_sysctl_ttl $IP4DST
+
+ teardown_interfaces
+ return 0
+}
+
+ipforwarding_v4_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ipforwarding_v6_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+ipforwarding_fastforward_v4_cleanup()
+{
+ $DEBUG && dump
+ stop_httpd
+ cleanup
+}
+
+ipforwarding_fastforward_v6_cleanup()
+{
+ $DEBUG && dump
+ stop_httpd
+ cleanup
+}
+
+ipforwarding_misc_cleanup()
+{
+ $DEBUG && dump
+ stop_httpd
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case ipforwarding_v4
+ atf_add_test_case ipforwarding_v6
+ atf_add_test_case ipforwarding_fastforward_v4
+ atf_add_test_case ipforwarding_fastforward_v6
+ atf_add_test_case ipforwarding_misc
+}
diff --git a/contrib/netbsd-tests/net/net/t_ipaddress.sh b/contrib/netbsd-tests/net/net/t_ipaddress.sh
new file mode 100755
index 0000000..4cdd954
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_ipaddress.sh
@@ -0,0 +1,193 @@
+# $NetBSD: t_ipaddress.sh,v 1.9 2016/12/15 02:43:56 ozaki-r Exp $
+#
+# Copyright (c) 2015 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK_LOCAL=unix://commsock1
+BUS=bus
+
+DEBUG=${DEBUG:-false}
+
+test_same_address()
+{
+ local ip=10.0.0.1
+ local net=10.0.0/24
+
+ rump_server_start $SOCK_LOCAL
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ check_route $ip 'link#2' UHl lo0
+ check_route $net 'link#2' UC shmif0
+
+ # Delete the address
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip delete
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ check_route_no_entry $ip
+ check_route_no_entry $net
+
+ # Assign the same address again
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip/24
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ check_route $ip 'link#2' UHl lo0
+ check_route $net 'link#2' UC shmif0
+
+ # Delete the address again
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 $ip delete
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ check_route_no_entry $ip
+ check_route_no_entry $net
+
+ rump_server_destroy_ifaces
+}
+
+test_same_address6()
+{
+ local ip=fc00::1
+ local net=fc00::/64
+
+ rump_server_start $SOCK_LOCAL netinet6
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet6
+
+ check_route $ip 'link#2' UHl lo0
+ check_route $net 'link#2' UC shmif0
+
+ # Delete the address
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip delete
+
+ $DEBUG && rump.netstat -nr -f inet6
+
+ check_route_no_entry $ip
+ check_route_no_entry $net
+
+ # Assign the same address again
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet6
+
+ check_route $ip 'link#2' UHl lo0
+ check_route $net 'link#2' UC shmif0
+
+ # Delete the address again
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $ip delete
+
+ $DEBUG && rump.netstat -nr -f inet6
+
+ check_route_no_entry $ip
+ check_route_no_entry $net
+
+ rump_server_destroy_ifaces
+}
+
+test_auto_linklocal()
+{
+
+ rump_server_start $SOCK_LOCAL netinet6
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ #
+ # Test enabled auto linklocal
+ #
+
+ # Check default value
+ atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet6.ip6.auto_linklocal
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ # IPv6 link-local address is set
+ atf_check -s exit:0 -o match:"inet6 fe80::" rump.ifconfig shmif0
+
+ #
+ # Test disabled auto linklocal
+ #
+ atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet6.ip6.auto_linklocal=0
+
+ rump_server_add_iface $SOCK_LOCAL shmif1 $BUS
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ # IPv6 link-local address is not set
+ atf_check -s exit:0 -o not-match:"inet6 fe80::" rump.ifconfig shmif1
+
+ rump_server_destroy_ifaces
+}
+
+add_test()
+{
+ local name=$1
+ local desc="$2"
+
+ atf_test_case "ipaddr_${name}" cleanup
+ eval "ipaddr_${name}_head() { \
+ atf_set \"descr\" \"${desc}\"; \
+ atf_set \"require.progs\" \"rump_server\"; \
+ }; \
+ ipaddr_${name}_body() { \
+ test_${name}; \
+ }; \
+ ipaddr_${name}_cleanup() { \
+ $DEBUG && dump; \
+ cleanup; \
+ }"
+ atf_add_test_case "ipaddr_${name}"
+}
+
+atf_init_test_cases()
+{
+
+ add_test same_address "Assigning/deleting an IP address twice"
+ add_test same_address6 "Assigning/deleting an IPv6 address twice"
+ add_test auto_linklocal "Assigning an IPv6 link-local address automatically"
+}
diff --git a/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh b/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh
new file mode 100755
index 0000000..10e50fd
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_ipv6_lifetime.sh
@@ -0,0 +1,127 @@
+# $NetBSD: t_ipv6_lifetime.sh,v 1.6 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK=unix://sock
+BUS=./bus
+
+DEBUG=${DEBUG:-false}
+
+deprecated="[Dd][Ee][Pp][Rr][Ee][Cc][Aa][Tt][Ee][Dd]"
+
+atf_test_case basic cleanup
+
+basic_head()
+{
+ atf_set "descr" "Tests for IPv6 address lifetime"
+ atf_set "require.progs" "rump_server"
+}
+
+basic_body()
+{
+ local time=5
+ local bonus=2
+ local ip="fc00::1"
+
+ rump_server_start $SOCK netinet6
+ rump_server_add_iface $SOCK shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ # A normal IP address doesn't contain preferred/valid lifetime
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip
+ $DEBUG && rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o not-match:'pltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o not-match:'vltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete
+
+ # Setting only a preferred lifetime
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip pltime $time
+ $DEBUG && rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'vltime infty' rump.ifconfig -L shmif0
+ atf_check -s exit:0 sleep $(($time + $bonus))
+ $DEBUG && rump.ifconfig -L shmif0
+ # Should remain but marked as deprecated
+ atf_check -s exit:0 -o match:"$ip.+$deprecated" rump.ifconfig -L shmif0
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete
+
+ # Setting only a valid lifetime (invalid)
+ atf_check -s not-exit:0 -e match:'Invalid argument' \
+ rump.ifconfig shmif0 inet6 $ip vltime $time
+
+ # Setting both preferred and valid lifetimes (same value)
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip \
+ pltime $time vltime $time
+ $DEBUG && rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 sleep $(($time + $bonus))
+ $DEBUG && rump.ifconfig -L shmif0
+ # Shouldn't remain anymore
+ atf_check -s exit:0 -o not-match:"$ip" rump.ifconfig -L shmif0
+
+ # Setting both preferred and valid lifetimes (pltime > vltime)
+ atf_check -s not-exit:0 -e match:'Invalid argument' rump.ifconfig \
+ shmif0 inet6 $ip pltime $(($time * 2)) vltime $time
+
+ # Setting both preferred and valid lifetimes (pltime < vltime)
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip \
+ pltime $time vltime $((time * 2))
+ $DEBUG && rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'pltime' rump.ifconfig -L shmif0
+ atf_check -s exit:0 -o match:'vltime' rump.ifconfig -L shmif0
+
+ if sysctl machdep.cpu_brand 2>/dev/null | grep QEMU >/dev/null 2>&1
+ then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip delete
+ atf_skip "unreliable under qemu, skip until PR kern/43997 fixed"
+ fi
+
+ atf_check -s exit:0 sleep $(($time + $bonus))
+ $DEBUG && rump.ifconfig -L shmif0
+ # Should remain but marked as deprecated
+ atf_check -s exit:0 -o match:"$ip.+$deprecated" rump.ifconfig -L shmif0
+ atf_check -s exit:0 sleep $(($time + $bonus))
+ $DEBUG && rump.ifconfig -L shmif0
+ # Shouldn't remain anymore
+ atf_check -s exit:0 -o not-match:"$ip" rump.ifconfig -L shmif0
+
+ rump_server_destroy_ifaces
+}
+
+basic_cleanup()
+{
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case basic
+}
diff --git a/contrib/netbsd-tests/net/net/t_ipv6address.sh b/contrib/netbsd-tests/net/net/t_ipv6address.sh
new file mode 100755
index 0000000..539a16d
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_ipv6address.sh
@@ -0,0 +1,387 @@
+# $NetBSD: t_ipv6address.sh,v 1.12 2016/12/14 02:50:42 ozaki-r Exp $
+#
+# Copyright (c) 2015 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+
+SERVER="rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet"
+SERVER="${SERVER} -lrumpnet_shmif -lrumpdev"
+SERVER6="${SERVER} -lrumpnet_netinet6"
+
+SOCKSRC=unix://commsock1
+SOCKFWD=unix://commsock2
+SOCKDST=unix://commsock3
+IP6SRCNW=fc00:1::0/64
+IP6SRC=fc00:1::1
+IP6DSTNW=fc00:2::0/64
+IP6DST=fc00:2::1
+IP6FWD0=fc00:3::1
+BUS1=bus1
+BUS2=bus2
+BUSSRC=bus_src
+BUSDST=bus_dst
+
+DEBUG=${DEBUG:-true}
+TIMEOUT=3
+
+atf_test_case linklocal cleanup
+atf_test_case linklocal_ops cleanup
+
+setup()
+{
+ atf_check -s exit:0 ${SERVER6} ${SOCKSRC}
+ atf_check -s exit:0 ${SERVER6} ${SOCKFWD}
+ atf_check -s exit:0 ${SERVER6} ${SOCKDST}
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKDST}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 -o match:"0 -> 1" rump.sysctl \
+ -w net.inet6.ip6.forwarding=1
+ unset RUMP_SERVER
+
+ setup_ifcfg
+
+ export RUMP_SERVER=${SOCKSRC}
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKDST}
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+}
+setup_ifcfg()
+{
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS1}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUSSRC}
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKDST}
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS2}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUSDST}
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr ${BUS1}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr ${BUS2}
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ unset RUMP_SERVER
+}
+
+setup_route()
+{
+ local tmp_rump_server=$RUMP_SERVER
+
+ local src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0`
+ local dst_if0_lladdr=`get_linklocal_addr ${SOCKDST} shmif0`
+ local fwd_if0_lladdr=`get_linklocal_addr ${SOCKFWD} shmif0`
+ local fwd_if1_lladdr=`get_linklocal_addr ${SOCKFWD} shmif1`
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s ignore -o ignore -e ignore \
+ rump.route delete -inet6 default ${fwd_if0_lladdr}%shmif0
+ atf_check -s exit:0 -o match:"add net default:" \
+ rump.route add -inet6 default ${fwd_if0_lladdr}%shmif0
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6SRC}
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKDST}
+ atf_check -s ignore -o ignore -e ignore \
+ rump.route delete -inet6 default ${fwd_if1_lladdr}%shmif0
+ atf_check -s exit:0 -o match:"add net default:" \
+ rump.route add -inet6 default ${fwd_if1_lladdr}%shmif0
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DST}
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ atf_check -s ignore -o ignore -e ignore \
+ rump.route delete -inet6 ${IP6SRCNW} ${src_if0_lladdr}%shmif0
+ atf_check -s exit:0 -o match:"add net" \
+ rump.route add -inet6 ${IP6SRCNW} ${src_if0_lladdr}%shmif0
+
+ atf_check -s ignore -o ignore -e ignore \
+ rump.route delete -inet6 ${IP6DSTNW} ${dst_if0_lladdr}%shmif1
+ atf_check -s exit:0 -o match:"add net" \
+ rump.route add -inet6 ${IP6DSTNW} ${dst_if0_lladdr}%shmif1
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ $DEBUG && rump.netstat -rn -f inet6
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=$tmp_rump_server
+}
+
+cleanup_bus()
+{
+ local tmp_rump_server=$RUMP_SERVER
+
+ $DEBUG && dump_bus
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 rump.ifconfig shmif0 down
+ atf_check -s exit:0 rump.ifconfig shmif0 -linkstr
+ atf_check -s exit:0 rump.ifconfig shmif1 down
+ atf_check -s exit:0 rump.ifconfig shmif1 -linkstr
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKDST}
+ atf_check -s exit:0 rump.ifconfig shmif0 down
+ atf_check -s exit:0 rump.ifconfig shmif0 -linkstr
+ atf_check -s exit:0 rump.ifconfig shmif1 down
+ atf_check -s exit:0 rump.ifconfig shmif1 -linkstr
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ atf_check -s exit:0 rump.ifconfig shmif0 down
+ atf_check -s exit:0 rump.ifconfig shmif0 -linkstr
+ atf_check -s exit:0 rump.ifconfig shmif1 down
+ atf_check -s exit:0 rump.ifconfig shmif1 -linkstr
+ unset RUMP_SERVER
+
+ atf_check -s exit:0 rm ${BUSSRC}
+ atf_check -s exit:0 rm ${BUSDST}
+ atf_check -s exit:0 rm ${BUS1}
+ atf_check -s exit:0 rm ${BUS2}
+
+ setup_ifcfg
+
+ export RUMP_SERVER=$tmp_rump_server
+}
+
+cleanup_rump_servers()
+{
+
+ env RUMP_SERVER=${SOCKSRC} rump.halt
+ env RUMP_SERVER=${SOCKDST} rump.halt
+ env RUMP_SERVER=${SOCKFWD} rump.halt
+}
+
+dump_bus()
+{
+
+ shmif_dumpbus -p - ${BUSSRC} 2>/dev/null| tcpdump -n -e -r -
+ shmif_dumpbus -p - ${BUSDST} 2>/dev/null| tcpdump -n -e -r -
+ shmif_dumpbus -p - ${BUS1} 2>/dev/null| tcpdump -n -e -r -
+ shmif_dumpbus -p - ${BUS2} 2>/dev/null| tcpdump -n -e -r -
+}
+
+_dump()
+{
+
+ export RUMP_SERVER=${SOCKSRC}
+ rump.ndp -n -a
+ rump.netstat -nr -f inet6
+ export RUMP_SERVER=${SOCKDST}
+ rump.ndp -n -a
+ rump.netstat -nr -f inet6
+ export RUMP_SERVER=${SOCKFWD}
+ rump.ndp -n -a
+ rump.netstat -nr -f inet6
+ unset RUMP_SERVER
+}
+
+linklocal_head()
+{
+ atf_set "descr" \
+ "Test for bassically function of the IPv6 linklocal address"
+ atf_set "require.progs" \
+ "rump_server rump.route rump.ifconfig rump.ping6"
+}
+
+linklocal_body()
+{
+ setup
+
+ local src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0`
+ local src_if1_lladdr=`get_linklocal_addr ${SOCKSRC} shmif1`
+ local dst_if0_lladdr=`get_linklocal_addr ${SOCKDST} shmif0`
+ local fwd_if0_lladdr=`get_linklocal_addr ${SOCKFWD} shmif0`
+ local fwd_if1_lladdr=`get_linklocal_addr ${SOCKFWD} shmif1`
+
+ export RUMP_SERVER=${SOCKSRC}
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # link local address to link local address
+
+ atf_check -s not-exit:0 -e match:"No route to host" \
+ rump.ping6 -c 1 -X $TIMEOUT -n ${fwd_if0_lladdr}
+
+ atf_check -s exit:0 -o match:"0.0% packet loss" \
+ rump.ping6 -c 1 -X $TIMEOUT -n ${fwd_if0_lladdr}%shmif0
+
+ atf_check -s ignore -o empty -e ignore \
+ -x "shmif_dumpbus -p - ${BUSSRC} | tcpdump -r - -n -p icmp6"
+ atf_check -s ignore -o not-empty -e ignore \
+ -x "shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6"
+
+ cleanup_bus
+
+ atf_check -s not-exit:0 -o ignore -e ignore \
+ rump.ping6 -c 1 -X $TIMEOUT -n -S ${src_if1_lladdr}%shmif1 \
+ ${fwd_if0_lladdr}%shmif0
+ atf_check -s ignore -o not-match:"${src_if1_lladdr}" -e ignore \
+ -x "shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6"
+ $DEBUG && shmif_dumpbus -p - ${BUS1} | tcpdump -r - -n -p icmp6
+ unset RUMP_SERVER
+
+ # link local address to host address
+ export RUMP_SERVER=${SOCKFWD}
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6FWD0}
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 -o match:"add net default:" \
+ rump.route add -inet6 default ${fwd_if0_lladdr}%shmif0
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig shmif0
+ $DEBUG && _dump
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 -o match:"0.0% packet loss" \
+ rump.ping6 -c 1 -X $TIMEOUT -n -S ${src_if0_lladdr}%shmif0 ${IP6FWD0}
+ unset RUMP_SERVER
+
+ export RUMP_SERVER=${SOCKFWD}
+ # host address to link local address
+ atf_check -s exit:0 -o match:"0.0% packet loss" \
+ rump.ping6 -c 1 -X $TIMEOUT -n ${src_if0_lladdr}%shmif0
+ atf_check -s not-exit:0 -o match:"100.0% packet loss" \
+ rump.ping6 -c 1 -X $TIMEOUT -n ${src_if1_lladdr}%shmif0
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6FWD0} delete
+
+ unset RUMP_SERVER
+
+ # forwarding with link local address
+ setup_route
+
+ export RUMP_SERVER=${SOCKSRC}
+ atf_check -s exit:0 -o match:"0.0% packet loss" rump.ping6 -c 1 \
+ -X $TIMEOUT -n -S ${IP6SRC} ${IP6DST}
+
+ cleanup_bus
+ $DEBUG && rump.ifconfig shmif0
+ atf_check -s not-exit:0 -o match:"100.0% packet loss" rump.ping6 -c 1 \
+ -X $TIMEOUT -n -S ${src_if0_lladdr}%shmif0 ${IP6DST}
+ atf_check -s ignore -o not-match:"${src_if0_lladdr}" -e ignore \
+ -x "shmif_dumpbus -p - ${BUS2} | tcpdump -r - -n -p icmp6"
+
+ cleanup_bus
+ atf_check -s not-exit:0 -o match:"100.0% packet loss" rump.ping6 -c 1 \
+ -X $TIMEOUT -n -S ${IP6SRC} ${dst_if0_lladdr}%shmif0
+ atf_check -s ignore -o not-empty -e ignore \
+ -x "shmif_dumpbus -p - ${BUS2} | tcpdump -r - -n -p icmp6"
+
+ unset RUMP_SERVER
+
+}
+
+linklocal_cleanup()
+{
+
+ $DEBUG && _dump
+ $DEBUG && dump_bus
+ cleanup_rump_servers
+}
+
+linklocal_ops_head()
+{
+
+ atf_set "descr" \
+ "Test for various operations to IPv6 linklocal addresses"
+ atf_set "require.progs" "rump_server rump.route rump.ndp"
+}
+
+linklocal_ops_body()
+{
+ local src_if0_lladdr=
+
+ setup
+
+ src_if0_lladdr=`get_linklocal_addr ${SOCKSRC} shmif0`
+
+ export RUMP_SERVER=${SOCKSRC}
+
+ # route get
+ atf_check -s exit:0 -o match:"${src_if0_lladdr}" \
+ rump.route get -inet6 ${src_if0_lladdr}%shmif0
+
+ # route get without an interface name (zone index)
+ atf_check -s not-exit:0 -e match:"not in table" \
+ rump.route get -inet6 ${src_if0_lladdr}
+
+ # ndp
+ atf_check -s exit:0 -o match:"${src_if0_lladdr}" \
+ rump.ndp -n ${src_if0_lladdr}%shmif0
+
+ # ndp without an interface name (zone index)
+ atf_check -s not-exit:0 -o ignore -e match:"no entry" \
+ rump.ndp -n ${src_if0_lladdr}
+}
+
+
+linklocal_ops_cleanup()
+{
+
+ cleanup_rump_servers
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case linklocal
+ atf_add_test_case linklocal_ops
+}
diff --git a/contrib/netbsd-tests/net/net/t_mtudisc.sh b/contrib/netbsd-tests/net/net/t_mtudisc.sh
new file mode 100755
index 0000000..a99d652
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_mtudisc.sh
@@ -0,0 +1,192 @@
+# $NetBSD: t_mtudisc.sh,v 1.8 2016/12/21 01:16:18 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKLOCAL=unix://commsock1
+SOCKGATEWAY=unix://commsock2
+SOCKREMOTE=unix://commsock3
+HTML_FILE=index.html
+
+DEBUG=${DEBUG:-false}
+
+atf_test_case mtudisc_basic cleanup
+
+mtudisc_basic_head()
+{
+ atf_set "descr" "Tests for IPv4 Path MTU Dicorvery basic behavior"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_server()
+{
+ local sock=$1
+ local if=$2
+ local bus=$3
+ local ip=$4
+
+ rump_server_add_iface $sock $if $bus
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig $if $ip
+ atf_check -s exit:0 rump.ifconfig $if up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig $if
+}
+
+prepare_download_file()
+{
+ local file=$1
+ local data="0123456789"
+
+ touch $file
+ for i in `seq 1 512`
+ do
+ echo $data >> $file
+ done
+}
+
+do_http_get()
+{
+ local ip=$1
+ local ret=$2
+ local timeout=5
+
+ # get the webpage
+ atf_check -s exit:$ret env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ftp -q $timeout -o ./out http://$ip/$HTML_FILE
+}
+
+mtudisc_basic_body()
+{
+ local pkt=
+ local local_ip=10.0.0.2
+ local gateway_local_ip=10.0.0.1
+ local gateway_remote_ip=10.0.1.1
+ local remote_ip=10.0.1.2
+ local prefixlen=24
+
+ rump_server_start $SOCKLOCAL
+ rump_server_start $SOCKGATEWAY
+ rump_server_start $SOCKREMOTE
+
+ #
+ # Setup servers
+ #
+ # [local server] [gateway server] [remote server with httpd]
+ # | 10.0.0.2 10.0.0.1 | | 10.0.1.1 10.0.1.2 |
+ # shmif0(mtu=1500) ----- shmif1(mtu=1280) shmif0(mtu=1500) ----- shmif0(mtu=1500)
+ #
+
+ # Assign IP addresses
+ setup_server $SOCKLOCAL shmif0 bus1 $local_ip/$prefixlen
+ setup_server $SOCKGATEWAY shmif0 bus1 $gateway_local_ip/$prefixlen
+ setup_server $SOCKGATEWAY shmif1 bus2 $gateway_remote_ip/$prefixlen
+ setup_server $SOCKREMOTE shmif0 bus2 $remote_ip/$prefixlen
+
+ ### Setup gateway server
+ export RUMP_SERVER=$SOCKGATEWAY
+
+ # Set mtu of shmif0 to 1280
+ export RUMP_SERVER=$SOCKGATEWAY
+ atf_check -s exit:0 rump.ifconfig shmif0 mtu 1280
+
+ # Enable IPv4 forwarding
+ atf_check -s exit:0 rump.sysctl -w -q net.inet.ip.forwarding=1
+
+ ### Setup remote server
+ export RUMP_SERVER=$SOCKREMOTE
+
+ # Check default value
+ atf_check -s exit:0 -o match:"1" rump.sysctl -n net.inet.ip.mtudisc
+
+ # Start httpd daemon
+ prepare_download_file $HTML_FILE
+ start_httpd $SOCKREMOTE $remote_ip
+ $DEBUG && rump.netstat -a -f inet
+
+ # Teach the peer thar 10.0.0.2(local serer) is behind 10.0.1.1(gateway server)
+ atf_check -s exit:0 -o ignore rump.route add $local_ip/32 $gateway_remote_ip
+
+ ### Setup local server
+ export RUMP_SERVER=$SOCKLOCAL
+
+ # Teach the peer thar 10.0.1.2(remote serer) is behind 10.0.0.1(gateway server)
+ atf_check -s exit:0 -o ignore rump.route add $remote_ip/32 $gateway_local_ip
+
+ # Don't accept fragmented packets
+ atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.maxfragpackets=0
+
+ #
+ # Test disabled path mtu discorvery
+ #
+ export RUMP_SERVER=$SOCKREMOTE
+ atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.mtudisc=0
+
+ # Get the webpage (expect: failed)
+ export RUMP_SERVER=$SOCKLOCAL
+ do_http_get $remote_ip 1
+ $DEBUG && extract_new_packets bus2 > ./out
+ $DEBUG && cat ./out
+
+ # Check path mtu size on remote server
+ export RUMP_SERVER=$SOCKREMOTE
+ atf_check -s exit:0 \
+ -o match:"^10.0.0.2 +10.0.1.1 +UGHS +- +- +- +shmif0" \
+ rump.netstat -nr -f inet
+
+ #
+ # Test enabled path mtu discorvery
+ #
+ export RUMP_SERVER=$SOCKREMOTE
+ atf_check -s exit:0 -o ignore rump.sysctl -w -q net.inet.ip.mtudisc=1
+
+ # Get the webpage (expect: success)
+ export RUMP_SERVER=$SOCKLOCAL
+ do_http_get $remote_ip 0
+ $DEBUG && extract_new_packets bus2 > ./out
+ $DEBUG && cat ./out
+
+ # Check path mtu size on remote server
+ export RUMP_SERVER=$SOCKREMOTE
+ atf_check -s exit:0 \
+ -o match:"^10.0.0.2 +10.0.1.1 +UGHS +- +- +1280 +shmif0" \
+ rump.netstat -nr -f inet
+
+ rump_server_destroy_ifaces
+}
+
+mtudisc_basic_cleanup()
+{
+ $DEBUG && dump
+ stop_httpd
+ cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case mtudisc_basic
+}
diff --git a/contrib/netbsd-tests/net/net/t_mtudisc6.sh b/contrib/netbsd-tests/net/net/t_mtudisc6.sh
new file mode 100755
index 0000000..93bc12e
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_mtudisc6.sh
@@ -0,0 +1,179 @@
+# $NetBSD: t_mtudisc6.sh,v 1.5 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKLOCAL=unix://commsock1
+SOCKGATEWAY=unix://commsock2
+SOCKREMOTE=unix://commsock3
+HTML_FILE=index.html
+
+DEBUG=${DEBUG:-false}
+
+atf_test_case mtudisc6_basic cleanup
+
+mtudisc6_basic_head()
+{
+
+ atf_set "descr" "Tests for IPv6 Path MTU Dicorvery basic behavior"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_server()
+{
+ local sock=$1
+ local if=$2
+ local bus=$3
+ local ip=$4
+
+ rump_server_add_iface $sock $if $bus
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig $if inet6 $ip
+ atf_check -s exit:0 rump.ifconfig $if up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig $if
+}
+
+prepare_download_file()
+{
+ local file=$1
+ local data="0123456789"
+
+ touch $file
+ for i in `seq 1 512`
+ do
+ echo $data >> $file
+ done
+}
+
+do_http_get()
+{
+ local ip=$1
+ local ret=$2
+ local timeout=5
+
+ # get the webpage
+ atf_check -s exit:$ret env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ftp -q $timeout -o ./out "http://[$ip]/$HTML_FILE"
+}
+
+mtudisc6_basic_body()
+{
+ local pkt=
+ local local_ip=fc00:0:0:1::2
+ local gateway_local_ip=fc00:0:0:1::1
+ local gateway_remote_ip=fc00:0:0:2::1
+ local remote_ip=fc00:0:0:2::2
+ local prefixlen=64
+
+ rump_server_start $SOCKLOCAL netinet6
+ rump_server_start $SOCKGATEWAY netinet6
+ rump_server_start $SOCKREMOTE netinet6
+
+ #
+ # Setup servers
+ #
+ # [local server] [gateway server] [remote server]
+ # | | | |
+ # shmif0(1500) -- shmif1(1280) shmif0(1500) -- shmif0(1500)
+ #
+
+ # Assign IP addresses
+ setup_server $SOCKLOCAL shmif0 bus1 $local_ip/$prefixlen
+ setup_server $SOCKGATEWAY shmif0 bus1 $gateway_local_ip/$prefixlen
+ setup_server $SOCKGATEWAY shmif1 bus2 $gateway_remote_ip/$prefixlen
+ setup_server $SOCKREMOTE shmif0 bus2 $remote_ip/$prefixlen
+
+ ### Setup gateway server
+ export RUMP_SERVER=$SOCKGATEWAY
+
+ # Set MTU of shmif0 to 1280
+ export RUMP_SERVER=$SOCKGATEWAY
+ atf_check -s exit:0 rump.ifconfig shmif0 mtu 1280
+
+ # Enable IPv6 forwarding
+ atf_check -s exit:0 rump.sysctl -w -q net.inet6.ip6.forwarding=1
+
+ ### Setup remote server
+ export RUMP_SERVER=$SOCKREMOTE
+
+ # Start httpd daemon
+ prepare_download_file $HTML_FILE
+ start_httpd $SOCKREMOTE $remote_ip
+ $DEBUG && rump.netstat -a
+
+ # Teach the peer that local serer is behind gateway server
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 $local_ip/128 $gateway_remote_ip
+
+ # Check path MTU size on remote server
+ atf_check -s exit:0 \
+ -o match:"^$local_ip +$gateway_remote_ip +UGHS +- +- +- +shmif0" \
+ rump.netstat -nr -f inet6
+
+ ### Setup local server
+ export RUMP_SERVER=$SOCKLOCAL
+
+ # Teach the peer that remote serer is behind gateway server
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 $remote_ip/128 $gateway_local_ip
+
+ # Don't accept fragmented packets
+ atf_check -s exit:0 -o ignore \
+ rump.sysctl -w -q net.inet6.ip6.maxfragpackets=0
+
+ #
+ # Test enabled path MTU discorvery
+ #
+ # Get the webpage (expect: success)
+ export RUMP_SERVER=$SOCKLOCAL
+ do_http_get $remote_ip 0
+ $DEBUG && extract_new_packets bus2 > ./out
+ $DEBUG && cat ./out
+
+ # Check path MTU size on remote server
+ export RUMP_SERVER=$SOCKREMOTE
+ atf_check -s exit:0 \
+ -o match:"^$local_ip +$gateway_remote_ip +UGHS +- +- +1280 +shmif0" \
+ rump.netstat -nr -f inet6
+
+ rump_server_destroy_ifaces
+}
+
+mtudisc6_basic_cleanup()
+{
+
+ $DEBUG && dump
+ stop_httpd
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case mtudisc6_basic
+}
diff --git a/contrib/netbsd-tests/net/net/t_ping6_opts.sh b/contrib/netbsd-tests/net/net/t_ping6_opts.sh
new file mode 100755
index 0000000..e2e774e
--- /dev/null
+++ b/contrib/netbsd-tests/net/net/t_ping6_opts.sh
@@ -0,0 +1,380 @@
+# $NetBSD: t_ping6_opts.sh,v 1.8 2016/11/25 08:51:17 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCKSRC=unix://commsock1
+SOCKFWD=unix://commsock2
+SOCKDST=unix://commsock3
+IP6SRC=fc00:0:0:1::2
+IP6SRCGW=fc00:0:0:1::1
+IP6DSTGW=fc00:0:0:2::1
+IP6DST=fc00:0:0:2::2
+BUS_SRCGW=bus1
+BUS_DSTGW=bus2
+
+IP6SRC2=fc00:0:0:1::3
+IP6SRCGW2=fc00:0:0:1::254
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=1
+
+#
+# Utility functions
+#
+setup_endpoint()
+{
+ local sock=${1}
+ local addr=${2}
+ local bus=${3}
+ local gw=${4}
+
+ rump_server_add_iface $sock shmif0 $bus
+
+ export RUMP_SERVER=${sock}
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr}
+ atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw}
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ if $DEBUG; then
+ rump.ifconfig shmif0
+ rump.netstat -nr
+ fi
+}
+
+setup_forwarder()
+{
+
+ rump_server_add_iface $SOCKFWD shmif0 $BUS_SRCGW
+ rump_server_add_iface $SOCKFWD shmif1 $BUS_DSTGW
+
+ export RUMP_SERVER=$SOCKFWD
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW}
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ if $DEBUG; then
+ rump.netstat -nr
+ rump.sysctl net.inet6.ip6.forwarding
+ fi
+}
+
+setup_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1
+}
+
+setup6()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKFWD netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_endpoint $SOCKSRC $IP6SRC $BUS_SRCGW $IP6SRCGW
+ setup_endpoint $SOCKDST $IP6DST $BUS_DSTGW $IP6DSTGW
+ setup_forwarder
+}
+
+check_echo_request_pkt()
+{
+ local pkt="$1 > $2: .+ echo request"
+
+ extract_new_packets $BUS_SRCGW > ./out
+ $DEBUG && echo $pkt
+ $DEBUG && cat ./out
+ atf_check -s exit:0 -o match:"$pkt" cat ./out
+}
+
+check_echo_request_pkt_with_macaddr()
+{
+ local pkt="$1 > $2, .+ $3 > $4: .+ echo request"
+
+ extract_new_packets $BUS_SRCGW > ./out
+ $DEBUG && echo $pkt
+ $DEBUG && cat ./out
+ atf_check -s exit:0 -o match:"$pkt" cat ./out
+}
+
+check_echo_request_pkt_with_macaddr_and_rthdr0()
+{
+ local pkt=
+
+ pkt="$1 > $2, .+ $3 > $4:"
+ pkt="$pkt srcrt \\(len=2, type=0, segleft=1, \\[0\\]$5\\)"
+ pkt="$pkt .+ echo request"
+
+ extract_new_packets $BUS_SRCGW > ./out
+ $DEBUG && echo $pkt
+ $DEBUG && cat ./out
+ atf_check -s exit:0 -o match:"$pkt" cat ./out
+}
+
+#
+# Tests
+#
+atf_test_case ping6_opts_sourceaddr cleanup
+ping6_opts_sourceaddr_head()
+{
+
+ atf_set "descr" "tests of ping6 -S option"
+ atf_set "require.progs" "rump_server"
+}
+
+ping6_opts_sourceaddr_body()
+{
+
+ setup6
+ setup_forwarding6
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt $IP6SRC $IP6DST
+
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6SRC2
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt $IP6SRC $IP6DST
+
+ # ping6 -S <sourceaddr>
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -S $IP6SRC $IP6DST
+ check_echo_request_pkt $IP6SRC $IP6DST
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -S $IP6SRC2 $IP6DST
+ check_echo_request_pkt $IP6SRC2 $IP6DST
+
+ rump_server_destroy_ifaces
+}
+
+ping6_opts_sourceaddr_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ping6_opts_interface cleanup
+ping6_opts_interface_head()
+{
+
+ atf_set "descr" "tests of ping6 -I option"
+ atf_set "require.progs" "rump_server"
+}
+
+ping6_opts_interface_body()
+{
+ local shmif0_lladdr=
+ local shmif1_lladdr=
+ local gw_lladdr=
+
+ setup6
+ setup_forwarding6
+
+ shmif0_lladdr=$(get_linklocal_addr ${SOCKSRC} shmif0)
+ gw_lladdr=$(get_linklocal_addr ${SOCKFWD} shmif0)
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $gw_lladdr
+ check_echo_request_pkt $shmif0_lladdr $gw_lladdr
+
+ rump_server_add_iface $SOCKSRC shmif1 $BUS_SRCGW
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+ shmif1_lladdr=$(get_linklocal_addr ${SOCKSRC} shmif1)
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $gw_lladdr
+ check_echo_request_pkt $shmif0_lladdr $gw_lladdr
+
+ # ping6 -I <interface>
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -I shmif0 $gw_lladdr
+ check_echo_request_pkt $shmif0_lladdr $gw_lladdr
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -I shmif1 $gw_lladdr
+ check_echo_request_pkt $shmif1_lladdr $gw_lladdr
+
+ rump_server_destroy_ifaces
+}
+
+ping6_opts_interface_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ping6_opts_gateway cleanup
+ping6_opts_gateway_head()
+{
+
+ atf_set "descr" "tests of ping6 -g option"
+ atf_set "require.progs" "rump_server"
+}
+
+ping6_opts_gateway_body()
+{
+ local my_macaddr=
+ local gw_shmif0_macaddr=
+ local gw_shmif2_macaddr=
+
+ setup6
+ setup_forwarding6
+
+ my_macaddr=$(get_macaddr ${SOCKSRC} shmif0)
+ gw_shmif0_macaddr=$(get_macaddr ${SOCKFWD} shmif0)
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST
+
+ rump_server_add_iface $SOCKFWD shmif2 $BUS_SRCGW
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 rump.ifconfig shmif2 inet6 $IP6SRCGW2
+ atf_check -s exit:0 rump.ifconfig -w 10
+ gw_shmif2_macaddr=$(get_macaddr ${SOCKFWD} shmif2)
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST
+
+ # ping6 -g <gateway>
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -g $IP6SRCGW $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -g $IP6SRCGW2 $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6DST
+
+ rump_server_destroy_ifaces
+}
+
+ping6_opts_gateway_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case ping6_opts_hops cleanup
+ping6_opts_hops_head()
+{
+
+ atf_set "descr" "tests of ping6 hops (Type 0 Routing Header)"
+ atf_set "require.progs" "rump_server"
+}
+
+ping6_opts_hops_body()
+{
+ local my_macaddr=
+ local gw_shmif0_macaddr=
+ local gw_shmif2_macaddr=
+
+ setup6
+ setup_forwarding6
+
+ my_macaddr=$(get_macaddr ${SOCKSRC} shmif0)
+ gw_shmif0_macaddr=$(get_macaddr ${SOCKFWD} shmif0)
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST
+
+ rump_server_add_iface $SOCKFWD shmif2 $BUS_SRCGW
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 rump.ifconfig shmif2 inet6 $IP6SRCGW2
+ atf_check -s exit:0 rump.ifconfig -w 10
+ gw_shmif2_macaddr=$(get_macaddr ${SOCKFWD} shmif2)
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6DST
+ check_echo_request_pkt_with_macaddr \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6DST
+
+ # ping6 hops
+
+ # ping6 fails expectedly because the kernel doesn't support
+ # to receive packets with type 0 routing headers, but we can
+ # check whether a sent packet is correct.
+ atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ $IP6SRCGW $IP6DST
+ check_echo_request_pkt_with_macaddr_and_rthdr0 \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW $IP6DST
+
+ atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ $IP6SRCGW2 $IP6DST
+ check_echo_request_pkt_with_macaddr_and_rthdr0 \
+ $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6SRCGW2 $IP6DST
+
+ # ping6 -g <gateway> hops
+ atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -g $IP6SRCGW $IP6SRCGW $IP6DST
+ check_echo_request_pkt_with_macaddr_and_rthdr0 \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW $IP6DST
+
+ atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -g $IP6SRCGW2 $IP6SRCGW2 $IP6DST
+ check_echo_request_pkt_with_macaddr_and_rthdr0 \
+ $my_macaddr $gw_shmif2_macaddr $IP6SRC $IP6SRCGW2 $IP6DST
+
+ # ping6 -g <gateway> hops, but different nexthops (is it valid?)
+ atf_check -s not-exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT \
+ -g $IP6SRCGW $IP6SRCGW2 $IP6DST
+ check_echo_request_pkt_with_macaddr_and_rthdr0 \
+ $my_macaddr $gw_shmif0_macaddr $IP6SRC $IP6SRCGW2 $IP6DST
+
+ rump_server_destroy_ifaces
+}
+
+ping6_opts_hops_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case ping6_opts_sourceaddr
+ atf_add_test_case ping6_opts_interface
+ atf_add_test_case ping6_opts_gateway
+ atf_add_test_case ping6_opts_hops
+}
diff --git a/contrib/netbsd-tests/net/net/t_tcp.c b/contrib/netbsd-tests/net/net/t_tcp.c
index 8972a0f..fd1f1e9 100644
--- a/contrib/netbsd-tests/net/net/t_tcp.c
+++ b/contrib/netbsd-tests/net/net/t_tcp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: t_tcp.c,v 1.3 2013/10/17 12:53:28 christos Exp $ */
+/* $NetBSD: t_tcp.c,v 1.4 2016/03/04 18:52:01 christos Exp $ */
/*-
* Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#ifdef __RCSID
-__RCSID("$Id: t_tcp.c,v 1.3 2013/10/17 12:53:28 christos Exp $");
+__RCSID("$Id: t_tcp.c,v 1.4 2016/03/04 18:52:01 christos Exp $");
#endif
/* Example code. Should block; does with accept not paccept. */
@@ -61,6 +61,10 @@ __RCSID("$Id: t_tcp.c,v 1.3 2013/10/17 12:53:28 christos Exp $");
#define FAIL(msg, ...) ATF_CHECK_MSG(0, msg, ## __VA_ARGS__); goto fail
#endif
+#ifdef __linux__
+#define paccept(a, b, c, d, e) accept4((a), (b), (c), (e))
+#endif
+
static void
ding(int al)
{
@@ -70,7 +74,8 @@ static void
paccept_block(bool pacceptblock, bool fcntlblock)
{
int srvr = -1, clnt = -1, as = -1;
- int ok, fl, n;
+ int ok, fl;
+ ssize_t n;
char buf[10];
struct sockaddr_in sin, ba;
struct sigaction sa;
@@ -105,10 +110,12 @@ paccept_block(bool pacceptblock, bool fcntlblock)
/* may not connect first time */
ok = connect(clnt, (struct sockaddr *) &ba, addrlen);
+ if (ok != -1 || errno != EINPROGRESS)
+ FAIL("expected connect to fail");
as = paccept(srvr, NULL, NULL, NULL, pacceptblock ? 0 : SOCK_NONBLOCK);
ok = connect(clnt, (struct sockaddr *) &ba, addrlen);
if (ok == -1 && errno != EISCONN)
- FAIL("both connects failed");
+ FAIL("connect failed");
#if 0
fl = fcntl(srvr, F_GETFL, 0);
diff --git a/contrib/netbsd-tests/net/net_common.sh b/contrib/netbsd-tests/net/net_common.sh
new file mode 100755
index 0000000..df21a88
--- /dev/null
+++ b/contrib/netbsd-tests/net/net_common.sh
@@ -0,0 +1,314 @@
+# $NetBSD: net_common.sh,v 1.11 2017/01/10 05:55:34 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+#
+# Common utility functions for tests/net
+#
+
+HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK=sysctl=yes"
+
+extract_new_packets()
+{
+ local bus=$1
+ local old=./.__old
+
+ if [ ! -f $old ]; then
+ old=/dev/null
+ fi
+
+ shmif_dumpbus -p - $bus 2>/dev/null| \
+ tcpdump -n -e -r - 2>/dev/null > ./.__new
+ diff -u $old ./.__new |grep '^+' |cut -d '+' -f 2 > ./.__diff
+ mv -f ./.__new ./.__old
+ cat ./.__diff
+}
+
+check_route()
+{
+ local target=$1
+ local gw=$2
+ local flags=${3:-\.\+}
+ local ifname=${4:-\.\+}
+
+ target=$(echo $target |sed 's/\./\\./g')
+ if [ "$gw" = "" ]; then
+ gw=".+"
+ else
+ gw=$(echo $gw |sed 's/\./\\./g')
+ fi
+
+ atf_check -s exit:0 -e ignore \
+ -o match:"^$target +$gw +$flags +- +- +.+ +$ifname" \
+ rump.netstat -rn
+}
+
+check_route_flags()
+{
+
+ check_route "$1" "" "$2" ""
+}
+
+check_route_gw()
+{
+
+ check_route "$1" "$2" "" ""
+}
+
+check_route_no_entry()
+{
+ local target=$(echo $1 |sed 's/\./\\./g')
+
+ atf_check -s exit:0 -e ignore -o not-match:"^$target" \
+ rump.netstat -rn
+}
+
+get_linklocal_addr()
+{
+
+ export RUMP_SERVER=${1}
+ rump.ifconfig ${2} inet6 |
+ awk "/fe80/ {sub(/%$2/, \"\"); sub(/\\/[0-9]*/, \"\"); print \$2;}"
+ unset RUMP_SERVER
+
+ return 0
+}
+
+get_macaddr()
+{
+
+ env RUMP_SERVER=${1} \
+ rump.ifconfig ${2} |awk '/address/ {print $2;}'
+}
+
+HTTPD_PID=./.__httpd.pid
+start_httpd()
+{
+ local sock=$1
+ local ip=$2
+ local backup=$RUMP_SERVER
+
+ export RUMP_SERVER=$sock
+
+ # start httpd in daemon mode
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ /usr/libexec/httpd -P $HTTPD_PID -i $ip -b -s $(pwd)
+
+ export RUMP_SERVER=$backup
+
+ sleep 3
+}
+
+stop_httpd()
+{
+
+ if [ -f $HTTPD_PID ]; then
+ kill -9 $(cat $HTTPD_PID)
+ rm -f $HTTPD_PID
+ sleep 1
+ fi
+}
+
+BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet \
+ -lrumpnet_shmif -lrumpdev"
+FS_LIBS="$BASIC_LIBS -lrumpvfs -lrumpfs_ffs"
+
+# We cannot keep variables between test phases, so need to store in files
+_rump_server_socks=./.__socks
+_rump_server_ifaces=./.__ifaces
+_rump_server_buses=./.__buses
+
+_rump_server_start_common()
+{
+ local sock=$1
+ local libs=
+
+ shift 1
+ libs="$*"
+
+ atf_check -s exit:0 rump_server $libs $sock
+
+ echo $sock >> $_rump_server_socks
+ $DEBUG && cat $_rump_server_socks
+}
+
+rump_server_start()
+{
+ local sock=$1
+ local _libs=
+ local libs="$BASIC_LIBS"
+
+ shift 1
+ _libs="$*"
+
+ for lib in $_libs; do
+ libs="$libs -lrumpnet_$lib"
+ done
+
+ _rump_server_start_common $sock $libs
+
+ return 0
+}
+
+rump_server_fs_start()
+{
+ local sock=$1
+ local _libs=
+ local libs="$FS_LIBS"
+
+ shift 1
+ _libs="$*"
+
+ for lib in $_libs; do
+ libs="$libs -lrumpnet_$lib"
+ done
+
+ _rump_server_start_common $sock $libs
+
+ return 0
+}
+
+rump_server_add_iface()
+{
+ local sock=$1
+ local ifname=$2
+ local bus=$3
+ local backup=$RUMP_SERVER
+
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 rump.ifconfig $ifname create
+ atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus
+ export RUMP_SERVER=$backup
+
+ echo $sock $ifname >> $_rump_server_ifaces
+ $DEBUG && cat $_rump_server_ifaces
+
+ echo $bus >> $_rump_server_buses
+ cat $_rump_server_buses |sort -u >./.__tmp
+ mv -f ./.__tmp $_rump_server_buses
+ $DEBUG && cat $_rump_server_buses
+
+ return 0
+}
+
+rump_server_destroy_ifaces()
+{
+ local backup=$RUMP_SERVER
+
+ $DEBUG && cat $_rump_server_ifaces
+
+ # Try to dump states before destroying interfaces
+ for sock in $(cat $_rump_server_socks); do
+ export RUMP_SERVER=$sock
+ atf_check -s exit:0 -o ignore rump.ifconfig
+ atf_check -s exit:0 -o ignore rump.netstat -nr
+ # XXX still need hijacking
+ atf_check -s exit:0 -o ignore $HIJACKING rump.netstat -i -a
+ atf_check -s exit:0 -o ignore rump.arp -na
+ atf_check -s exit:0 -o ignore rump.ndp -na
+ atf_check -s exit:0 -o ignore $HIJACKING ifmcstat
+ done
+
+ # XXX using pipe doesn't work. See PR bin/51667
+ #cat $_rump_server_ifaces | while read sock ifname; do
+ while read sock ifname; do
+ export RUMP_SERVER=$sock
+ if rump.ifconfig -l |grep -q $ifname; then
+ atf_check -s exit:0 rump.ifconfig $ifname destroy
+ fi
+ atf_check -s exit:0 -o ignore rump.ifconfig
+ done < $_rump_server_ifaces
+ export RUMP_SERVER=$backup
+
+ return 0
+}
+
+rump_server_halt_servers()
+{
+ local backup=$RUMP_SERVER
+
+ $DEBUG && cat $_rump_server_socks
+ for sock in $(cat $_rump_server_socks); do
+ env RUMP_SERVER=$sock rump.halt
+ done
+ export RUMP_SERVER=$backup
+
+ return 0
+}
+
+rump_server_dump_servers()
+{
+ local backup=$RUMP_SERVER
+
+ $DEBUG && cat $_rump_server_socks
+ for sock in $(cat $_rump_server_socks); do
+ echo "### Dumping $sock"
+ export RUMP_SERVER=$sock
+ rump.ifconfig
+ rump.netstat -nr
+ # XXX still need hijacking
+ $HIJACKING rump.netstat -i -a
+ rump.arp -na
+ rump.ndp -na
+ $HIJACKING ifmcstat
+ $HIJACKING dmesg
+ done
+ export RUMP_SERVER=$backup
+
+ if [ -f rump_server.core ]; then
+ gdb -ex bt /usr/bin/rump_server rump_server.core
+ strings rump_server.core |grep panic
+ fi
+ return 0
+}
+
+rump_server_dump_buses()
+{
+
+ if [ ! -f $_rump_server_buses ]; then
+ return 0
+ fi
+
+ $DEBUG && cat $_rump_server_buses
+ for bus in $(cat $_rump_server_buses); do
+ echo "### Dumping $bus"
+ shmif_dumpbus -p - $bus 2>/dev/null| tcpdump -n -e -r -
+ done
+ return 0
+}
+
+cleanup()
+{
+
+ rump_server_halt_servers
+}
+
+dump()
+{
+
+ rump_server_dump_servers
+ rump_server_dump_buses
+}
diff --git a/contrib/netbsd-tests/net/route/t_change.sh b/contrib/netbsd-tests/net/route/t_change.sh
index 3618aee..260cad0 100755
--- a/contrib/netbsd-tests/net/route/t_change.sh
+++ b/contrib/netbsd-tests/net/route/t_change.sh
@@ -1,4 +1,4 @@
-# $NetBSD: t_change.sh,v 1.4 2013/02/19 21:08:25 joerg Exp $
+# $NetBSD: t_change.sh,v 1.9 2016/11/07 05:25:37 ozaki-r Exp $
#
# Copyright (c) 2011 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -26,18 +26,21 @@
#
netserver=\
-"rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet"
+"rump_server -lrumpdev -lrumpnet -lrumpnet_net \
+ -lrumpnet_netinet -lrumpnet_shmif"
export RUMP_SERVER=unix://commsock
-atf_test_case reject2blackhole cleanup
-reject2blackhole_head()
+DEBUG=${DEBUG:-false}
+
+atf_test_case route_change_reject2blackhole cleanup
+route_change_reject2blackhole_head()
{
atf_set "descr" "Change a reject route to blackhole"
atf_set "require.progs" "rump_server"
}
-reject2blackhole_body()
+route_change_reject2blackhole_body()
{
atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
@@ -49,10 +52,242 @@ reject2blackhole_body()
atf_check -s exit:0 -o ignore \
rump.route change 207.46.197.32 127.0.0.1 -blackhole
atf_check -s exit:0 -o match:' UGHBS ' -e ignore -x \
- "rump.netstat -rn -f inet | grep ^207.46| grep ^207.46"
+ "rump.netstat -rn -f inet | grep ^207.46"
+}
+
+route_change_reject2blackhole_cleanup()
+{
+
+ env RUMP_SERVER=unix://commsock rump.halt
+}
+
+atf_test_case route_change_gateway cleanup
+route_change_gateway_head()
+{
+
+ atf_set "descr" "Change the gateway of a route"
+ atf_set "require.progs" "rump_server"
+}
+
+route_change_gateway_body()
+{
+
+ atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 192.168.0.0/24 10.0.0.1
+ atf_check -s exit:0 -o match:'10.0.0.1' -x \
+ "rump.route -n show -inet | grep ^192.168"
+ atf_check -s exit:0 -o ignore \
+ rump.route change -net 192.168.0.0/24 10.0.0.254
+ atf_check -s exit:0 -o match:'10.0.0.254' -x \
+ "rump.route -n show -inet | grep ^192.168"
+}
+
+route_change_gateway_cleanup()
+{
+
+ env RUMP_SERVER=unix://commsock rump.halt
+}
+
+atf_test_case route_change_ifa cleanup
+route_change_ifa_head()
+{
+
+ atf_set "descr" "Change the ifa (local address) of a route"
+ atf_set "require.progs" "rump_server"
+}
+
+route_change_ifa_body()
+{
+
+ atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24
+ atf_check -s exit:0 rump.ifconfig shmif0 alias 10.0.0.11/24
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 192.168.0.0/24 10.0.0.1
+ atf_check -s exit:0 -o match:'10.0.0.1' -x \
+ "rump.route -n show -inet | grep ^192.168"
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.10
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Change the local address of the route
+ atf_check -s exit:0 -o ignore \
+ rump.route change -net 192.168.0.0/24 10.0.0.1 -ifa 10.0.0.11
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.11
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+}
+
+route_change_ifa_cleanup()
+{
+
+ env RUMP_SERVER=unix://commsock rump.halt
+}
+
+atf_test_case route_change_ifp cleanup
+route_change_ifp_head()
+{
+
+ atf_set "descr" "Change a route based on an interface (ifp)"
+ atf_set "require.progs" "rump_server"
+}
+
+route_change_ifp_body()
+{
+
+ atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up
+
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif1 10.0.0.11/24 up
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 192.168.0.0/24 10.0.0.1
+ atf_check -s exit:0 -o match:'10.0.0.1' -x \
+ "rump.route -n show -inet | grep ^192.168"
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.10
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Change a route based on an interface
+ atf_check -s exit:0 -o ignore \
+ rump.route change -net 192.168.0.0/24 10.0.0.1 -ifp shmif1
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.11
+ interface: shmif1
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+}
+
+route_change_ifp_cleanup()
+{
+
+ env RUMP_SERVER=unix://commsock rump.halt
+}
+
+atf_test_case route_change_ifp_ifa cleanup
+route_change_ifp_head()
+{
+
+ atf_set "descr" "Change a route with -ifp and -ifa"
+ atf_set "require.progs" "rump_server"
+}
+
+route_change_ifp_ifa_body()
+{
+
+ atf_check -s exit:0 ${netserver} ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.10/24 up
+
+ atf_check -s exit:0 rump.ifconfig shmif1 create
+ atf_check -s exit:0 rump.ifconfig shmif1 linkstr bus
+ atf_check -s exit:0 rump.ifconfig shmif1 10.0.0.11/24 up
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 192.168.0.0/24 10.0.0.1
+ atf_check -s exit:0 -o match:'10.0.0.1' -x \
+ "rump.route -n show -inet | grep ^192.168"
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.10
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Change a route with -ifa and -ifp
+ atf_check -s exit:0 -o ignore \
+ rump.route change -net 192.168.0.0/24 -ifa 10.0.0.1 -ifp shmif1
+ $DEBUG && rump.route -n show -inet
+ cat >./expect <<-EOF
+ route to: 192.168.0.1
+destination: 192.168.0.0
+ mask: 255.255.255.0
+ gateway: 10.0.0.1
+ local addr: 10.0.0.11
+ interface: shmif1
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get 192.168.0.1 > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
}
-reject2blackhole_cleanup()
+route_change_ifp_ifa_cleanup()
{
env RUMP_SERVER=unix://commsock rump.halt
@@ -61,5 +296,9 @@ reject2blackhole_cleanup()
atf_init_test_cases()
{
- atf_add_test_case reject2blackhole
+ atf_add_test_case route_change_reject2blackhole
+ atf_add_test_case route_change_gateway
+ atf_add_test_case route_change_ifa
+ atf_add_test_case route_change_ifp
+ atf_add_test_case route_change_ifp_ifa
}
diff --git a/contrib/netbsd-tests/net/route/t_flags.sh b/contrib/netbsd-tests/net/route/t_flags.sh
new file mode 100755
index 0000000..457e3f5
--- /dev/null
+++ b/contrib/netbsd-tests/net/route/t_flags.sh
@@ -0,0 +1,334 @@
+# $NetBSD: t_flags.sh,v 1.15 2016/12/21 02:46:08 ozaki-r Exp $
+#
+# Copyright (c) 2015 The NetBSD Foundation, Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK_LOCAL=unix://commsock1
+SOCK_PEER=unix://commsock2
+SOCK_GW=unix://commsock3
+BUS=bus1
+BUS2=bus2
+
+DEBUG=${DEBUG:-false}
+
+setup_local()
+{
+
+ rump_server_start $SOCK_LOCAL
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.2/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+setup_peer()
+{
+
+ rump_server_start $SOCK_PEER
+ rump_server_add_iface $SOCK_PEER shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.1/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+setup_gw()
+{
+
+ rump_server_start $SOCK_GW
+ rump_server_add_iface $SOCK_GW shmif0 $BUS
+ rump_server_add_iface $SOCK_GW shmif1 $BUS2
+
+ export RUMP_SERVER=$SOCK_GW
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 10.0.0.254/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 10.0.2.1/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 alias 10.0.2.2/24
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif1 up
+
+ # Wait until DAD completes (10 sec at most)
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+ atf_check -s not-exit:0 -x "rump.ifconfig shmif1 |grep -q tentative"
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet
+}
+
+test_lo()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Up, Host, local
+ check_route_flags 127.0.0.1 UHl
+}
+
+test_connected()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Up, Host, LLINFO, local
+ check_route_flags 10.0.0.2 UHl
+
+ # Up, Cloning
+ check_route_flags 10.0.0/24 UC
+}
+
+test_default_gateway()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Static
+ check_route_flags default UGS
+}
+
+test_static()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Static route to host
+ atf_check -s exit:0 -o ignore rump.route add 10.0.1.1 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Host, Static
+ check_route_flags 10.0.1.1 UGHS
+
+ # Static route to network
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Static
+ check_route_flags 10.0.2/24 UGS
+}
+
+test_blackhole()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.0.1
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24
+
+ # Gateway must be lo0
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 10.0.0.0/24 127.0.0.1 -blackhole
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Blackhole, Static
+ check_route_flags 10.0.0/24 UGBS
+
+ atf_check -s not-exit:0 -o match:'100.0% packet loss' \
+ rump.ping -n -w 1 -c 1 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Shouldn't be created
+ check_route_no_entry 10.0.0.1
+}
+
+test_reject()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24
+
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.0.0/24 10.0.0.1 -reject
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Reject, Static
+ check_route_flags 10.0.0/24 UGRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'No route to host' \
+ rump.ping -n -w 1 -c 1 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Shouldn't be created
+ check_route_no_entry 10.0.0.1
+
+ # Gateway is lo0 (RTF_GATEWAY)
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -net 10.0.0.0/24 127.0.0.1 -reject
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Reject, Static
+ check_route_flags 10.0.0/24 UGRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'Network is unreachable' \
+ rump.ping -n -w 1 -c 1 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Shouldn't be created
+ check_route_no_entry 10.0.0.1
+
+ # Gateway is lo0 (RTF_HOST)
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -host 10.0.0.1/24 127.0.0.1 -iface -reject
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Host, Reject, Static
+ check_route_flags 10.0.0.1 UHRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'No route to host' \
+ rump.ping -n -w 1 -c 1 10.0.0.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ return 0
+}
+
+test_icmp_redirect()
+{
+
+ ### Testing Dynamic flag ###
+
+ #
+ # Setup a gateway 10.0.0.254. 10.0.2.1 is behind it.
+ #
+ setup_gw
+
+ #
+ # Teach the peer that 10.0.2.* is behind 10.0.0.254
+ #
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.2.0/24 10.0.0.254
+ # Up, Gateway, Static
+ check_route_flags 10.0.2/24 UGS
+
+ #
+ # Setup the default gateway to the peer, 10.0.0.1
+ #
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.route add default 10.0.0.1
+ # Up, Gateway, Static
+ check_route_flags default UGS
+
+ # Try ping 10.0.2.1
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.1
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Host, Dynamic
+ check_route_flags 10.0.2.1 UGHD
+ check_route_gw 10.0.2.1 10.0.0.254
+
+ export RUMP_SERVER=$SOCK_PEER
+ $DEBUG && rump.netstat -rn -f inet
+
+ ### Testing Modified flag ###
+
+ #
+ # Teach a wrong route to 10.0.2.2
+ #
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.route add 10.0.2.2 10.0.0.1
+ # Up, Gateway, Host, Static
+ check_route_flags 10.0.2.2 UGHS
+ check_route_gw 10.0.2.2 10.0.0.1
+
+ # Try ping 10.0.2.2
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 10.0.2.2
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Host, Modified, Static
+ check_route_flags 10.0.2.2 UGHMS
+ check_route_gw 10.0.2.2 10.0.0.254
+}
+
+test_announce()
+{
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore rump.route delete -net 10.0.0.0/24
+
+ atf_check -s exit:0 -o ignore rump.route add -net 10.0.0.0/24 10.0.0.1 -proxy
+ $DEBUG && rump.netstat -rn -f inet
+
+ # Up, Gateway, Static, proxy
+ check_route_flags 10.0.0/24 UGSp
+
+ # TODO test its behavior
+}
+
+add_test()
+{
+ local name=$1
+ local desc="$2"
+
+ atf_test_case "route_flags_${name}" cleanup
+ eval "route_flags_${name}_head() { \
+ atf_set \"descr\" \"${desc}\"; \
+ atf_set \"require.progs\" \"rump_server\"; \
+ }; \
+ route_flags_${name}_body() { \
+ setup_local; \
+ setup_peer; \
+ test_${name}; \
+ rump_server_destroy_ifaces; \
+ }; \
+ route_flags_${name}_cleanup() { \
+ $DEBUG && dump; \
+ cleanup; \
+ }"
+ atf_add_test_case "route_flags_${name}"
+}
+
+atf_init_test_cases()
+{
+
+ add_test lo "Tests route flags: loop back interface"
+ add_test connected "Tests route flags: connected route"
+ add_test default_gateway "Tests route flags: default gateway"
+ add_test static "Tests route flags: static route"
+ add_test blackhole "Tests route flags: blackhole route"
+ add_test reject "Tests route flags: reject route"
+ add_test icmp_redirect "Tests route flags: icmp redirect"
+ add_test announce "Tests route flags: announce flag"
+}
diff --git a/contrib/netbsd-tests/net/route/t_flags6.sh b/contrib/netbsd-tests/net/route/t_flags6.sh
new file mode 100755
index 0000000..e570829
--- /dev/null
+++ b/contrib/netbsd-tests/net/route/t_flags6.sh
@@ -0,0 +1,268 @@
+# $NetBSD: t_flags6.sh,v 1.12 2016/12/21 02:46:08 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+SOCK_LOCAL=unix://commsock1
+SOCK_PEER=unix://commsock2
+SOCK_GW=unix://commsock3
+BUS=bus1
+BUS2=bus2
+
+IP6_LOCAL=fc00::2
+IP6_PEER=fc00::1
+
+DEBUG=${DEBUG:-false}
+
+setup_local()
+{
+
+ rump_server_start $SOCK_LOCAL netinet6
+ rump_server_add_iface $SOCK_LOCAL shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_LOCAL
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $IP6_LOCAL
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+}
+
+setup_peer()
+{
+
+ rump_server_start $SOCK_PEER netinet6
+ rump_server_add_iface $SOCK_PEER shmif0 $BUS
+
+ export RUMP_SERVER=$SOCK_PEER
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 inet6 $IP6_PEER
+ atf_check -s exit:0 -o ignore rump.ifconfig shmif0 up
+ atf_check -s exit:0 -o ignore rump.ifconfig -w 10
+
+ $DEBUG && rump.ifconfig
+ $DEBUG && rump.netstat -rn -f inet6
+}
+
+test_lo6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Up, Host, local
+ check_route_flags fe80::1 UHl
+
+ # Up, Host, local
+ check_route_flags ::1 UHl
+}
+
+test_connected6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Up, Host, local
+ check_route_flags $IP6_LOCAL UHl
+
+ # Up, Connected
+ check_route_flags fc00::/64 UC
+}
+
+test_default_gateway6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.route add -inet6 default $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Static
+ check_route_flags default UGS
+}
+
+test_static6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Static route to host
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 fc00::1:1 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Host, Static
+ check_route_flags fc00::1:1 UGHS
+
+ # Static route to network
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -net fc00::/24 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Static
+ check_route_flags fc00::/24 UGS
+}
+
+test_blackhole6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6_PEER
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore \
+ rump.route delete -inet6 -net fc00::/64
+
+ # Gateway must be lo0
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -net fc00::/64 ::1 -blackhole
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Blackhole, Static
+ check_route_flags fc00::/64 UGBS
+
+ atf_check -s not-exit:0 -o match:'100.0% packet loss' \
+ rump.ping6 -n -X 1 -c 1 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Shouldn't be created
+ check_route_no_entry $IP6_PEER
+}
+
+test_reject6()
+{
+
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore \
+ rump.route delete -inet6 -net fc00::/64
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -net fc00::/64 $IP6_PEER -reject
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Reject, Static
+ check_route_flags fc00::/64 UGRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'No route to host' \
+ rump.ping6 -n -X 1 -c 1 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Shouldn't be created
+ check_route_no_entry $IP6_PEER
+
+ # Gateway is lo0 (RTF_GATEWAY)
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore \
+ rump.route delete -inet6 -net fc00::/64
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -net fc00::/64 ::1 -reject
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Reject, Static
+ check_route_flags fc00::/64 UGRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'Network is unreachable' \
+ rump.ping6 -n -X 1 -c 1 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Shouldn't be created
+ check_route_no_entry $IP6_PEER
+
+ # Gateway is lo0 (RTF_HOST)
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore \
+ rump.route delete -inet6 -net fc00::/64
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -host fc00::/64 ::1 -iface -reject
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Host, Reject, Static
+ check_route_flags fc00:: UHRS
+
+ atf_check -s not-exit:0 -o ignore -e match:'No route to host' \
+ rump.ping6 -n -X 1 -c 1 $IP6_PEER
+ $DEBUG && rump.netstat -rn -f inet6
+
+ return 0
+}
+
+test_announce6()
+{
+ export RUMP_SERVER=$SOCK_LOCAL
+
+ # Delete an existing route first
+ atf_check -s exit:0 -o ignore \
+ rump.route delete -inet6 -net fc00::/64
+
+ atf_check -s exit:0 -o ignore \
+ rump.route add -inet6 -net fc00::/64 $IP6_PEER -proxy
+ $DEBUG && rump.netstat -rn -f inet6
+
+ # Up, Gateway, Static, proxy
+ check_route_flags fc00::/64 UGSp
+
+ # TODO test its behavior
+}
+
+add_test()
+{
+ local name=$1
+ local desc="$2"
+
+ atf_test_case "route_flags_${name}" cleanup
+ eval "route_flags_${name}_head() { \
+ atf_set \"descr\" \"${desc}\"; \
+ atf_set \"require.progs\" \"rump_server\"; \
+ }; \
+ route_flags_${name}_body() { \
+ setup_local; \
+ setup_peer; \
+ test_${name}; \
+ rump_server_destroy_ifaces; \
+ }; \
+ route_flags_${name}_cleanup() { \
+ $DEBUG && dump; \
+ cleanup; \
+ }"
+ atf_add_test_case "route_flags_${name}"
+}
+
+atf_init_test_cases()
+{
+
+ add_test lo6 "Tests route flags: loop back interface"
+ add_test connected6 "Tests route flags: connected route"
+ add_test default_gateway6 "Tests route flags: default gateway"
+ add_test static6 "Tests route flags: static route"
+ add_test blackhole6 "Tests route flags: blackhole route"
+ add_test reject6 "Tests route flags: reject route"
+ add_test announce6 "Tests route flags: announce flag"
+}
diff --git a/contrib/netbsd-tests/net/route/t_route.sh b/contrib/netbsd-tests/net/route/t_route.sh
new file mode 100755
index 0000000..053f48f
--- /dev/null
+++ b/contrib/netbsd-tests/net/route/t_route.sh
@@ -0,0 +1,406 @@
+# $NetBSD: t_route.sh,v 1.10 2016/12/21 02:46:08 ozaki-r Exp $
+#
+# Copyright (c) 2016 Internet Initiative Japan Inc.
+# 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.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``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 FOUNDATION OR CONTRIBUTORS
+# 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.
+#
+
+# non_subnet_gateway
+SOCK_CLIENT=unix://commsock1
+SOCK_GW=unix://commsock2
+BUS=bus1
+
+# command_get
+SOCKSRC=unix://commsock1
+SOCKFWD=unix://commsock2
+SOCKDST=unix://commsock3
+IP4SRC=10.0.1.2
+IP4SRCGW=10.0.1.1
+IP4DSTGW=10.0.2.1
+IP4DST=10.0.2.2
+IP4DST_BCAST=10.0.2.255
+IP6SRC=fc00:0:0:1::2
+IP6SRCGW=fc00:0:0:1::1
+IP6DSTGW=fc00:0:0:2::1
+IP6DST=fc00:0:0:2::2
+BUS_SRCGW=bus1
+BUS_DSTGW=bus2
+
+DEBUG=${DEBUG:-false}
+TIMEOUT=1
+PING_OPTS="-n -c 1 -w $TIMEOUT"
+
+atf_test_case route_non_subnet_gateway cleanup
+route_non_subnet_gateway_head()
+{
+
+ atf_set "descr" "tests of a gateway not on the local subnet"
+ atf_set "require.progs" "rump_server"
+}
+
+route_non_subnet_gateway_body()
+{
+
+ rump_server_start $SOCK_CLIENT
+ rump_server_start $SOCK_GW
+
+ export RUMP_SERVER=${SOCK_GW}
+ rump_server_add_iface $SOCK_GW shmif0 $BUS
+ atf_check -s exit:0 rump.ifconfig shmif0 192.168.0.1
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+
+ # The gateway knows the client
+ atf_check -s exit:0 -o match:'add net 10.0.0.1: gateway shmif0' \
+ rump.route add -net 10.0.0.1/32 -link -cloning -iface shmif0
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ export RUMP_SERVER=${SOCK_CLIENT}
+ rump_server_add_iface $SOCK_CLIENT shmif0 $BUS
+ atf_check -s exit:0 rump.ifconfig shmif0 10.0.0.1/32
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ # Don't know a route to the gateway yet
+ atf_check -s not-exit:0 -o match:'100.0% packet loss' \
+ -e match:'No route to host' rump.ping $PING_OPTS 192.168.0.1
+
+ # Teach a route to the gateway
+ atf_check -s exit:0 -o match:'add net 192.168.0.1: gateway shmif0' \
+ rump.route add -net 192.168.0.1/32 -link -cloning -iface shmif0
+ atf_check -s exit:0 -o match:'add net default: gateway 192.168.0.1' \
+ rump.route add default -ifa 10.0.0.1 192.168.0.1
+
+ $DEBUG && rump.netstat -nr -f inet
+
+ # Be reachable to the gateway
+ atf_check -s exit:0 -o ignore rump.ping $PING_OPTS 192.168.0.1
+
+ rump_server_destroy_ifaces
+}
+
+route_non_subnet_gateway_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_test_case route_command_get cleanup
+atf_test_case route_command_get6 cleanup
+route_command_get_head()
+{
+
+ atf_set "descr" "tests of route get command"
+ atf_set "require.progs" "rump_server"
+}
+
+route_command_get6_head()
+{
+
+ atf_set "descr" "tests of route get command (IPv6)"
+ atf_set "require.progs" "rump_server"
+}
+
+setup_endpoint()
+{
+ local sock=${1}
+ local addr=${2}
+ local bus=${3}
+ local mode=${4}
+ local gw=${5}
+
+ export RUMP_SERVER=${sock}
+ rump_server_add_iface $sock shmif0 $bus
+ if [ $mode = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr}
+ atf_check -s exit:0 -o ignore rump.route add -inet6 default ${gw}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00
+ atf_check -s exit:0 -o ignore rump.route add default ${gw}
+ fi
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ if $DEBUG; then
+ rump.ifconfig shmif0
+ rump.netstat -nr
+ fi
+}
+
+setup_forwarder()
+{
+ mode=${1}
+
+ rump_server_add_iface $SOCKFWD shmif0 $BUS_SRCGW
+ rump_server_add_iface $SOCKFWD shmif1 $BUS_DSTGW
+
+ export RUMP_SERVER=$SOCKFWD
+ if [ $mode = "ipv6" ]; then
+ atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${IP6SRCGW}
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 ${IP6DSTGW}
+ else
+ atf_check -s exit:0 rump.ifconfig shmif0 inet ${IP4SRCGW} netmask 0xffffff00
+ atf_check -s exit:0 rump.ifconfig shmif1 inet ${IP4DSTGW} netmask 0xffffff00
+ fi
+
+ atf_check -s exit:0 rump.ifconfig shmif0 up
+ atf_check -s exit:0 rump.ifconfig shmif1 up
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ if $DEBUG; then
+ rump.netstat -nr
+ if [ $mode = "ipv6" ]; then
+ rump.sysctl net.inet6.ip6.forwarding
+ else
+ rump.sysctl net.inet.ip.forwarding
+ fi
+ fi
+}
+
+setup_forwarding()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet.ip.forwarding=1
+}
+
+setup_forwarding6()
+{
+ export RUMP_SERVER=$SOCKFWD
+ atf_check -s exit:0 -o ignore rump.sysctl -w net.inet6.ip6.forwarding=1
+}
+
+setup()
+{
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKFWD
+ rump_server_start $SOCKDST
+
+ setup_endpoint $SOCKSRC $IP4SRC $BUS_SRCGW ipv4 $IP4SRCGW
+ setup_endpoint $SOCKDST $IP4DST $BUS_DSTGW ipv4 $IP4DSTGW
+ setup_forwarder ipv4
+}
+
+setup6()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKFWD netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_endpoint $SOCKSRC $IP6SRC $BUS_SRCGW ipv6 $IP6SRCGW
+ setup_endpoint $SOCKDST $IP6DST $BUS_DSTGW ipv6 $IP6DSTGW
+ setup_forwarder ipv6
+}
+
+test_route_get()
+{
+
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.netstat -nr -f inet
+ $DEBUG && rump.arp -n -a
+
+ # Make sure an ARP cache to the gateway doesn't exist
+ rump.arp -d $IP4SRCGW
+
+ # Local
+ cat >./expect <<-EOF
+ route to: 10.0.1.2
+destination: 10.0.1.2
+ local addr: 10.0.1.2
+ interface: lo0
+ flags: <UP,HOST,DONE,LLINFO,LOCAL>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get $IP4SRC > ./output
+ $DEBUG && cat ./expect ./output
+ # XXX: omit the last line because expire is unstable on rump kernel.
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Neighbor
+ cat >./expect <<-EOF
+ route to: 10.0.1.1
+destination: 10.0.1.0
+ mask: 255.255.255.0
+ local addr: 10.0.1.2
+ interface: shmif0
+ flags: <UP,DONE,CONNECTED>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get $IP4SRCGW > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Remote host
+ cat >./expect <<-EOF
+ route to: 10.0.2.2
+destination: default
+ mask: default
+ gateway: 10.0.1.1
+ local addr: 10.0.1.2
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get $IP4DST > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Create a ARP cache
+ atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP4SRCGW
+
+ # Neighbor with a cache (no different from w/o cache)
+ cat >./expect <<-EOF
+ route to: 10.0.1.1
+destination: 10.0.1.0
+ mask: 255.255.255.0
+ local addr: 10.0.1.2
+ interface: shmif0
+ flags: <UP,DONE,CONNECTED>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get $IP4SRCGW > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+}
+
+test_route_get6()
+{
+
+ export RUMP_SERVER=$SOCKSRC
+ $DEBUG && rump.netstat -nr -f inet
+ $DEBUG && rump.ndp -n -a
+
+ # Make sure an ARP cache to the gateway doesn't exist
+ rump.ndp -d $IP6SRCGW
+
+ # Local
+ cat >./expect <<-EOF
+ route to: fc00:0:0:1::2
+destination: fc00:0:0:1::2
+ local addr: fc00:0:0:1::2
+ interface: lo0
+ flags: <UP,HOST,DONE,LLINFO,LOCAL>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get -inet6 $IP6SRC > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Neighbor
+ cat >./expect <<-EOF
+ route to: fc00:0:0:1::1
+destination: fc00:0:0:1::
+ mask: ffff:ffff:ffff:ffff::
+ local addr: fc00:0:0:1::2
+ interface: shmif0
+ flags: <UP,DONE,CONNECTED>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get -inet6 $IP6SRCGW > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Remote host
+ cat >./expect <<-EOF
+ route to: fc00:0:0:2::2
+destination: ::
+ mask: default
+ gateway: fc00:0:0:1::1
+ local addr: fc00:0:0:1::2
+ interface: shmif0
+ flags: <UP,GATEWAY,DONE,STATIC>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get -inet6 $IP6DST > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+
+ # Create a NDP cache
+ atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT $IP6SRCGW
+
+ # Neighbor with a cache (no different from w/o cache)
+ cat >./expect <<-EOF
+ route to: fc00:0:0:1::1
+destination: fc00:0:0:1::
+ mask: ffff:ffff:ffff:ffff::
+ local addr: fc00:0:0:1::2
+ interface: shmif0
+ flags: <UP,DONE,CONNECTED>
+ recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
+ EOF
+ rump.route -n get -inet6 $IP6SRCGW > ./output
+ $DEBUG && cat ./expect ./output
+ sed -i '$d' ./output
+ atf_check -s exit:0 diff ./expect ./output
+}
+
+route_command_get_body()
+{
+
+ setup
+ setup_forwarding
+ test_route_get
+ rump_server_destroy_ifaces
+}
+
+route_command_get6_body()
+{
+
+ setup6
+ setup_forwarding6
+ test_route_get6
+ rump_server_destroy_ifaces
+}
+
+route_command_get_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+route_command_get6_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case route_non_subnet_gateway
+ atf_add_test_case route_command_get
+ atf_add_test_case route_command_get6
+}
OpenPOWER on IntegriCloud