Skip to content

Instantly share code, notes, and snippets.

@ozaki-r
Last active August 23, 2019 07:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ozaki-r/37bec56f93f5a57dc98ed618e8db42a3 to your computer and use it in GitHub Desktop.
Save ozaki-r/37bec56f93f5a57dc98ed618e8db42a3 to your computer and use it in GitHub Desktop.
workaround rumphijck for vmstat
commit d8aa69b7abe780ed6778e23e3f68713f71d13d99
Author: Ryota Ozaki <ozaki-r@iij.ad.jp>
Date: Fri Aug 23 13:33:58 2019 +0900
Restore vmstat
diff --git a/tests/net/net_common.sh b/tests/net/net_common.sh
index 8b1790f9c5a..e224047b76c 100644
--- a/tests/net/net_common.sh
+++ b/tests/net/net_common.sh
@@ -341,8 +341,13 @@ rump_server_check_poolleaks()
{
local target=$1
- reqs=$($HIJACKING vmstat -mv | awk "/$target/ {print \$3;}")
- rels=$($HIJACKING vmstat -mv | awk "/$target/ {print \$5;}")
+ # XXX rumphijack doesn't work with a binary with suid/sgid bits like
+ # vmstat. Use a copied one to drop sgid bit as a workaround until
+ # vmstat stops using kvm(3) and the sgid bit.
+ cp /usr/bin/vmstat ./vmstat
+ reqs=$($HIJACKING ./vmstat -mv | awk "/$target/ {print \$3;}")
+ rels=$($HIJACKING ./vmstat -mv | awk "/$target/ {print \$5;}")
+ rm -f ./vmstat
atf_check_equal '$target$reqs' '$target$rels'
}
@@ -350,8 +355,7 @@ rump_server_check_poolleaks()
rump_server_check_memleaks()
{
- # XXX this doesn't work in some cases for unknown reasons
- #rump_server_check_poolleaks llentrypl
+ rump_server_check_poolleaks llentrypl
# This doesn't work for objects allocated through pool_cache
#rump_server_check_poolleaks mbpl
#rump_server_check_poolleaks mclpl
@@ -437,7 +441,10 @@ dump_kernel_stats()
rump.netstat -nr
# XXX still need hijacking
$HIJACKING rump.netstat -nai
- $HIJACKING vmstat -m
+ # XXX workaround for vmstat with the sgid bit
+ cp /usr/bin/vmstat ./vmstat
+ $HIJACKING ./vmstat -m
+ rm -f ./vmstat
rump.arp -na
rump.ndp -na
$HIJACKING ifmcstat
#! /usr/bin/atf-sh
# $NetBSD: net_common.sh,v 1.35 2019/08/20 09:53:45 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=path=/rump,socket=all:nolocal,sysctl=yes"
ONEDAYISH="(23h5[0-9]m|1d0h0m)[0-9]+s ?"
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()
{
RUMP_SERVER=${1} rump.ifconfig ${2} inet6 |
awk "/fe80/ {sub(/%$2/, \"\"); sub(/\\/[0-9]*/, \"\"); print \$2;}"
return 0
}
get_macaddr()
{
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
}
NC_PID=./.__nc.pid
start_nc_server()
{
local sock=$1
local port=$2
local outfile=$3
local proto=${4:-ipv4}
local backup=$RUMP_SERVER
local opts=
export RUMP_SERVER=$sock
if [ $proto = ipv4 ]; then
opts="-l -4"
else
opts="-l -6"
fi
env LD_PRELOAD=/usr/lib/librumphijack.so nc $opts $port > $outfile &
echo $! > $NC_PID
if [ $proto = ipv4 ]; then
$DEBUG && rump.netstat -a -f inet
else
$DEBUG && rump.netstat -a -f inet6
fi
export RUMP_SERVER=$backup
sleep 1
}
stop_nc_server()
{
if [ -f $NC_PID ]; then
kill -9 $(cat $NC_PID)
rm -f $NC_PID
sleep 1
fi
}
BASIC_LIBS="-lrumpnet -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif"
FS_LIBS="$BASIC_LIBS -lrumpdev -lrumpvfs -lrumpfs_ffs"
CRYPTO_LIBS="$BASIC_LIBS -lrumpdev -lrumpdev_opencrypto \
-lrumpkern_z -lrumpkern_crypto"
NPF_LIBS="$BASIC_LIBS -lrumpdev -lrumpvfs -lrumpdev_bpf -lrumpnet_npf"
CRYPTO_NPF_LIBS="$CRYPTO_LIBS -lrumpvfs -lrumpdev_bpf -lrumpnet_npf"
# 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
DEBUG_SYSCTL_ENTRIES="net.inet.arp.debug net.inet6.icmp6.nd6_debug \
net.inet.ipsec.debug"
IPSEC_KEY_DEBUG=${IPSEC_KEY_DEBUG:-false}
_rump_server_start_common()
{
local sock=$1
local backup=$RUMP_SERVER
shift 1
atf_check -s exit:0 rump_server "$@" "$sock"
if $DEBUG; then
# Enable debugging features in the kernel
export RUMP_SERVER=$sock
for ent in $DEBUG_SYSCTL_ENTRIES; do
if rump.sysctl -q $ent; then
atf_check -s exit:0 rump.sysctl -q -w $ent=1
fi
done
export RUMP_SERVER=$backup
fi
if $IPSEC_KEY_DEBUG; then
# Enable debugging features in the kernel
export RUMP_SERVER=$sock
if rump.sysctl -q net.key.debug; then
atf_check -s exit:0 \
rump.sysctl -q -w net.key.debug=0xffff
fi
export RUMP_SERVER=$backup
fi
echo $sock >> $_rump_server_socks
$DEBUG && cat $_rump_server_socks
}
rump_server_start()
{
local sock=$1
local lib=
local libs="$BASIC_LIBS"
shift 1
for lib
do
libs="$libs -lrumpnet_$lib"
done
_rump_server_start_common $sock $libs
return 0
}
rump_server_fs_start()
{
local sock=$1
local lib=
local libs="$FS_LIBS"
shift 1
for lib
do
libs="$libs -lrumpnet_$lib"
done
_rump_server_start_common $sock $libs
return 0
}
rump_server_crypto_start()
{
local sock=$1
local lib=
local libs="$CRYPTO_LIBS"
shift 1
for lib
do
libs="$libs -lrumpnet_$lib"
done
_rump_server_start_common $sock $libs
return 0
}
rump_server_npf_start()
{
local sock=$1
local lib=
local libs="$NPF_LIBS"
shift 1
for lib
do
libs="$libs -lrumpnet_$lib"
done
_rump_server_start_common $sock $libs
return 0
}
rump_server_crypto_npf_start()
{
local sock=$1
local lib=
local libs="$CRYPTO_NPF_LIBS"
shift 1
for lib
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
if [ -n "$bus" ]; then
atf_check -s exit:0 rump.ifconfig $ifname linkstr $bus
fi
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_check_poolleaks()
{
local target=$1
# XXX rumphijack doesn't work with a binary with suid/sgid bits like
# vmstat. Use a copied one to drop sgid bit as a workaround until
# vmstat stops using kvm(3) and the sgid bit.
cp /usr/bin/vmstat ./vmstat
reqs=$($HIJACKING ./vmstat -mv | awk "/$target/ {print \$3;}")
rels=$($HIJACKING ./vmstat -mv | awk "/$target/ {print \$5;}")
rm -f ./vmstat
atf_check_equal '$target$reqs' '$target$rels'
}
rump_server_check_memleaks()
{
rump_server_check_poolleaks llentrypl
# This doesn't work for objects allocated through pool_cache
#rump_server_check_poolleaks mbpl
#rump_server_check_poolleaks mclpl
#rump_server_check_poolleaks socket
}
rump_server_destroy_ifaces()
{
local backup=$RUMP_SERVER
local output=ignore
local reqs= rels=
$DEBUG && cat $_rump_server_ifaces
# Try to dump states before destroying interfaces
for sock in $(cat $_rump_server_socks); do
export RUMP_SERVER=$sock
if $DEBUG; then
output=save:/dev/stdout
fi
atf_check -s exit:0 -o $output rump.ifconfig
atf_check -s exit:0 -o $output rump.netstat -nr
# XXX still need hijacking
atf_check -s exit:0 -o $output $HIJACKING rump.netstat -nai
atf_check -s exit:0 -o $output rump.arp -na
atf_check -s exit:0 -o $output rump.ndp -na
atf_check -s exit:0 -o $output $HIJACKING ifmcstat
done
# XXX using pipe doesn't work. See PR bin/51667
#cat $_rump_server_ifaces | while read sock ifname; do
# Destroy interfaces in the reverse order
tac $_rump_server_ifaces > __ifaces
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 < __ifaces
rm -f __ifaces
for sock in $(cat $_rump_server_socks); do
export RUMP_SERVER=$sock
rump_server_check_memleaks
done
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
}
extract_rump_server_core()
{
if [ -f rump_server.core ]; then
gdb -ex bt /usr/bin/rump_server rump_server.core
# Extract kernel logs including a panic message
strings rump_server.core |grep -E '^\[.+\] '
fi
}
dump_kernel_stats()
{
local sock=$1
echo "### Dumping $sock"
export RUMP_SERVER=$sock
rump.ifconfig -av
rump.netstat -nr
# XXX still need hijacking
$HIJACKING rump.netstat -nai
# XXX workaround for vmstat with the sgid bit
cp /usr/bin/vmstat ./vmstat
$HIJACKING ./vmstat -m
rm -f ./vmstat
rump.arp -na
rump.ndp -na
$HIJACKING ifmcstat
$HIJACKING dmesg
}
rump_server_dump_servers()
{
local backup=$RUMP_SERVER
$DEBUG && cat $_rump_server_socks
for sock in $(cat $_rump_server_socks); do
dump_kernel_stats $sock
done
export RUMP_SERVER=$backup
extract_rump_server_core
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
}
skip_if_qemu()
{
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
}
test_create_destroy_common()
{
local sock=$1
local ifname=$2
local test_address=${3:-false}
local ipv4="10.0.0.1/24"
local ipv6="fc00::1"
export RUMP_SERVER=$sock
atf_check -s exit:0 rump.ifconfig $ifname create
atf_check -s exit:0 rump.ifconfig $ifname destroy
atf_check -s exit:0 rump.ifconfig $ifname create
atf_check -s exit:0 rump.ifconfig $ifname up
atf_check -s exit:0 rump.ifconfig $ifname down
atf_check -s exit:0 rump.ifconfig $ifname destroy
# Destroy while UP
atf_check -s exit:0 rump.ifconfig $ifname create
atf_check -s exit:0 rump.ifconfig $ifname up
atf_check -s exit:0 rump.ifconfig $ifname destroy
if ! $test_address; then
return
fi
# With an IPv4 address
atf_check -s exit:0 rump.ifconfig $ifname create
atf_check -s exit:0 rump.ifconfig $ifname inet $ipv4
atf_check -s exit:0 rump.ifconfig $ifname up
atf_check -s exit:0 rump.ifconfig $ifname destroy
# With an IPv6 address
atf_check -s exit:0 rump.ifconfig $ifname create
atf_check -s exit:0 rump.ifconfig $ifname inet6 $ipv6
atf_check -s exit:0 rump.ifconfig $ifname up
atf_check -s exit:0 rump.ifconfig $ifname destroy
unset RUMP_SERVER
}
# $NetBSD: t_ndp.sh,v 1.35 2019/08/19 03:20:27 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
IP6SRC2=fc00::3
IP6DST=fc00::2
IP6NET=fc00::0
DEBUG=${DEBUG:-false}
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 not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
atf_check -s not-exit:0 -o ignore -e match:'no entry' 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()
{
local macaddr=
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
# Shorten the expire time of cache entries
export RUMP_SERVER=$SOCKSRC
atf_check -s exit:0 -o match:'basereachable=7s0ms' \
rump.ndp -i shmif0 basereachable=7000
# Make a permanent cache entry to avoid sending an NS packet disturbing
# the test
macaddr=$(get_macaddr $SOCKSRC shmif0)
export RUMP_SERVER=$SOCKDST
atf_check -s exit:0 -o ignore rump.ndp -s $IP6SRC $macaddr
export RUMP_SERVER=$SOCKSRC
#
# Check if a cache is expired expectedly
#
atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
$DEBUG && rump.ndp -n -a
atf_check -s not-exit:0 -o ignore -e match:'no entry' 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 not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6SRC
# Expired but remains until GC sweaps it (1 day)
atf_check -s exit:0 -o match:"$ONEDAYISH" 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
# 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
check_route fc00::10 'b2:a0:20:00:00:10' UHLS shmif0
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
check_route_no_entry 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
check_route_flags $IP6DST UHL
check_route_flags fc00::11 UHLS
check_route_flags fc00::12 UHLS
# 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
#check_route_no_entry $IP6SRC
check_route_no_entry $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
check_route_flags fc00::11 UHLS
check_route_flags fc00::12 UHLS
$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
check_route fc00::10 'b2:a0:20:00:00:10' UHL shmif0
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 exit:0 rump.ndp -s $IP6SRC b2:a0:20:00:00:ff
$DEBUG && rump.ndp -n -a
atf_check -s not-exit:0 -e ignore rump.ndp -s $IP6SRC b2:a0:20:00:00:fe
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_test_case ndp_rtm cleanup
ndp_rtm_head()
{
atf_set "descr" "Tests for routing messages on operations of NDP entries"
atf_set "require.progs" "rump_server"
}
ndp_rtm_body()
{
local macaddr_src= macaddr_dst=
local file=./tmp
local pid= hdr= what= addr=
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
macaddr_src=$(get_macaddr $SOCKSRC shmif0)
macaddr_dst=$(get_macaddr $SOCKDST shmif0)
export RUMP_SERVER=$SOCKSRC
# Test ping and a resulting routing message (RTM_ADD)
rump.route -n monitor -c 1 > $file &
pid=$!
sleep 1
atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
wait $pid
$DEBUG && cat $file
hdr="RTM_ADD.+<UP,HOST,DONE,LLINFO,CLONED>"
what="<DST,GATEWAY>"
addr="$IP6DST link#2"
atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
cat $file
# Test ndp -d and resulting routing messages (RTM_DELETE)
rump.route -n monitor -c 1 > $file &
pid=$!
sleep 1
atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
wait $pid
$DEBUG && cat $file
hdr="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
what="<DST,GATEWAY>"
addr="$IP6DST $macaddr_dst"
atf_check -s exit:0 -o match:"$hdr" -o match:"$what" -o match:"$addr" \
grep -A 3 RTM_DELETE $file
rump_server_destroy_ifaces
}
ndp_rtm_cleanup()
{
$DEBUG && dump
cleanup
}
atf_test_case ndp_purge_on_route_change cleanup
ndp_purge_on_route_change_head()
{
atf_set "descr" "Tests if NDP entries are removed on route change"
atf_set "require.progs" "rump_server"
}
ndp_purge_on_route_change_body()
{
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
rump_server_add_iface $SOCKSRC shmif1 bus1
export RUMP_SERVER=$SOCKSRC
atf_check -s exit:0 rump.ifconfig shmif1 inet6 fc00:1::1
atf_check -s exit:0 rump.ifconfig -w 10
$DEBUG && rump.netstat -nr -f inet6
atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
atf_check -s exit:0 -o ignore \
rump.route change -inet6 -net $IP6NET/64 -ifp shmif1
$DEBUG && rump.netstat -nr -f inet6
$DEBUG && rump.ndp -na
# The entry was already removed on route change
atf_check -s not-exit:0 -o ignore -e match:'no entry' \
rump.ndp -n $IP6DST
rump_server_destroy_ifaces
}
ndp_purge_on_route_change_cleanup()
{
$DEBUG && dump
cleanup
}
atf_test_case ndp_purge_on_route_delete cleanup
ndp_purge_on_route_delete_head()
{
atf_set "descr" "Tests if NDP entries are removed on route delete"
atf_set "require.progs" "rump_server"
}
ndp_purge_on_route_delete_body()
{
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
$DEBUG && rump.netstat -nr -f inet6
atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
atf_check -s exit:0 -o ignore rump.route delete -inet6 -net $IP6NET/64
$DEBUG && rump.netstat -nr -f inet6
$DEBUG && rump.ndp -na
# The entry was already removed on route delete
atf_check -s not-exit:0 -o ignore -e match:'no entry' \
rump.ndp -n $IP6DST
rump_server_destroy_ifaces
}
ndp_purge_on_route_delete_cleanup()
{
$DEBUG && dump
cleanup
}
atf_test_case ndp_purge_on_ifdown cleanup
ndp_purge_on_ifdown_head()
{
atf_set "descr" "Tests if NDP entries are removed on interface down"
atf_set "require.progs" "rump_server"
}
ndp_purge_on_ifdown_body()
{
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
$DEBUG && rump.netstat -nr -f inet6
atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
# Shutdown the interface
atf_check -s exit:0 rump.ifconfig shmif0 down
$DEBUG && rump.netstat -nr -f inet6
$DEBUG && rump.ndp -na
# The entry was already removed on ifconfig down
atf_check -s not-exit:0 -o ignore -e match:'no entry' \
rump.ndp -n $IP6DST
rump_server_destroy_ifaces
}
ndp_purge_on_ifdown_cleanup()
{
$DEBUG && dump
cleanup
}
atf_test_case ndp_stray_entries cleanup
ndp_stray_entries_head()
{
atf_set "descr" "Tests if NDP entries are removed on route change"
atf_set "require.progs" "rump_server"
}
ndp_stray_entries_body()
{
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
rump_server_add_iface $SOCKSRC shmif1 bus1
export RUMP_SERVER=$SOCKSRC
atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6SRC2/64
atf_check -s exit:0 rump.ifconfig -w 10
$DEBUG && rump.netstat -nr -f inet6
atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
$DEBUG && rump.ndp -na
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
# Clean up
atf_check -s exit:0 -o ignore rump.ndp -c
atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
# ping from a different source address
atf_check -s exit:0 -o ignore \
rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
$DEBUG && rump.ndp -na
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
# ARP reply goes back via shmif1, so a cache is created on shmif1
atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
# Clean up by ndp -c
atf_check -s exit:0 -o ignore rump.ndp -c
atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
# ping from a different source address again
atf_check -s exit:0 -o ignore \
rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
# ARP reply doen't come
atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
# Cleanup caches on the destination
export RUMP_SERVER=$SOCKDST
$DEBUG && rump.ndp -na
atf_check -s exit:0 -o ignore rump.ndp -c
$DEBUG && rump.ndp -na
export RUMP_SERVER=$SOCKSRC
# ping from a different source address again
atf_check -s exit:0 -o ignore \
rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
# ARP reply goes back via shmif1
atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
# Clean up by ndp -d <ip>
atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
# Both entries should be deleted
atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
rump_server_destroy_ifaces
}
ndp_stray_entries_cleanup()
{
$DEBUG && dump
cleanup
}
atf_test_case ndp_cache_state cleanup
ndp_cache_state_head()
{
atf_set "descr" "Tests states of neighbor cache entries"
atf_set "require.progs" "rump_server"
}
check_cache_state()
{
local dst=$1
local state=$2
$DEBUG && rump.ndp -n $dst
atf_check -s exit:0 -o match:"^$dst.*$state " rump.ndp -n $dst
}
wait_until_stalled()
{
local dst=$1
local state=$2
$DEBUG && rump.ndp -n $dst
while true; do
rump.ndp -n $dst | grep -q "^$dst.*S " && break
sleep 1
done
$DEBUG && rump.ndp -n $dst
}
ndp_cache_state_body()
{
local macaddr=
rump_server_start $SOCKSRC netinet6
rump_server_start $SOCKDST netinet6
setup_dst_server
setup_src_server
# Shorten the expire time of cache entries
export RUMP_SERVER=$SOCKSRC
atf_check -s exit:0 -o match:'basereachable=7s0ms' \
rump.ndp -i shmif0 basereachable=7000
# Make a permanent cache entry to avoid sending an NS packet disturbing
# the test
macaddr=$(get_macaddr $SOCKSRC shmif0)
export RUMP_SERVER=$SOCKDST
atf_check -s exit:0 -o ignore rump.ndp -s $IP6SRC $macaddr
export RUMP_SERVER=$SOCKSRC
#
# Reachability confirmation (RFC 4861 7.3.3)
#
atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
# Receiving a solicited NA packet changes the state of the cache to REACHABLE
check_cache_state $IP6DST R
# The state of the cache transits to STALE after a while
wait_until_stalled $IP6DST
# Sending a packet on the cache will run a reachability confirmation
atf_check -s exit:0 -o ignore rump.ping6 -n -X $TIMEOUT -c 1 $IP6DST
sleep 1
# The state of the cache is changed to DELAY and stay for 5s, then
# send a NS packet and change the state to PROBE
check_cache_state $IP6DST D
sleep $((5 + 1))
# If the reachability confirmation is success, the state of the cache
# is changed to REACHABLE
check_cache_state $IP6DST R
}
ndp_cache_state_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
atf_add_test_case ndp_rtm
atf_add_test_case ndp_purge_on_route_change
atf_add_test_case ndp_purge_on_route_delete
atf_add_test_case ndp_purge_on_ifdown
atf_add_test_case ndp_stray_entries
atf_add_test_case ndp_cache_state
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment