1#!/usr/bin/env atf-sh 2#- 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2020 Alexander V. Chernikov 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28# 29 30. $(atf_get_srcdir)/../common/vnet.subr 31 32atf_test_case "fwd_ip_icmp_iface_fast_success" "cleanup" 33fwd_ip_icmp_iface_fast_success_head() { 34 35 atf_set descr 'Test valid IPv4 on-stick fastforwarding to iface' 36 atf_set require.user root 37 atf_set require.progs scapy 38} 39 40fwd_ip_icmp_iface_fast_success_body() { 41 42 vnet_init 43 44 ip4a="192.0.2.1" 45 ip4b="192.0.2.2" 46 plen=29 47 src_ip="192.0.2.3" 48 49 script_name="../common/sender.py" 50 51 epair=$(vnet_mkepair) 52 ifconfig ${epair}a up 53 ifconfig ${epair}a inet ${ip4a}/${plen} 54 55 jname="v4t-fwd_ip_icmp_iface_fast_success" 56 vnet_mkjail ${jname} ${epair}b 57 jexec ${jname} ifconfig ${epair}b up 58 jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen} 59 60 # Get router ip/mac 61 jail_ip=${ip4b} 62 jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'` 63 64 our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'` 65 66 jexec ${jname} sysctl net.inet.ip.forwarding=1 67 # As we're doing router-on-the-stick, turn sending IP redirects off: 68 jexec ${jname} sysctl net.inet.ip.redirect=0 69 70 # echo "LOCAL: ${local_ip} ${local_mac}" 71 # echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}" 72 73 atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \ 74 --test_name fwd_ip_icmp_fast \ 75 --smac ${our_mac} --dmac ${jail_mac} \ 76 --sip ${src_ip} --dip ${ip4a} \ 77 --iface ${epair}a 78 79 # check counters are valid 80 atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip 81} 82 83fwd_ip_icmp_iface_fast_success_cleanup() { 84 85 vnet_cleanup 86} 87 88atf_test_case "fwd_ip_icmp_gw_fast_success" "cleanup" 89fwd_ip_icmp_gw_fast_success_head() { 90 91 atf_set descr 'Test valid IPv4 on-stick fastforwarding to gw' 92 atf_set require.user root 93 atf_set require.progs scapy 94} 95 96fwd_ip_icmp_gw_fast_success_body() { 97 98 vnet_init 99 100 ip4a="192.0.2.1" 101 ip4b="192.0.2.2" 102 plen=29 103 src_ip="192.0.2.3" 104 dst_ip="192.0.2.4" 105 106 script_name="../common/sender.py" 107 108 epair=$(vnet_mkepair) 109 ifconfig ${epair}a up 110 ifconfig ${epair}a inet ${ip4a}/${plen} 111 112 jname="v4t-fwd_ip_icmp_gw_fast_success" 113 vnet_mkjail ${jname} ${epair}b 114 jexec ${jname} ifconfig ${epair}b up 115 jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen} 116 117 # Get router ip/mac 118 jail_ip=${ip4b} 119 jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'` 120 121 our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'` 122 123 jexec ${jname} sysctl net.inet.ip.forwarding=1 124 # As we're doing router-on-the-stick, turn sending IP redirects off: 125 jexec ${jname} sysctl net.inet.ip.redirect=0 126 127 # Add host route 128 jexec ${jname} route -4 add -host ${dst_ip} ${ip4a} 129 130 # echo "LOCAL: ${local_ip} ${local_mac}" 131 # echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}" 132 133 atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \ 134 --test_name fwd_ip_icmp_fast \ 135 --smac ${our_mac} --dmac ${jail_mac} \ 136 --sip ${src_ip} --dip ${dst_ip} \ 137 --iface ${epair}a 138 139 # check counters are valid 140 atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip 141} 142 143fwd_ip_icmp_gw_fast_success_cleanup() { 144 145 vnet_cleanup 146} 147 148atf_test_case "fwd_ip_icmp_iface_slow_success" "cleanup" 149fwd_ip_icmp_iface_slow_success_head() { 150 151 atf_set descr 'Test valid IPv4 on-stick "slow" forwarding to iface' 152 atf_set require.user root 153 atf_set require.progs scapy 154} 155 156fwd_ip_icmp_iface_slow_success_body() { 157 158 vnet_init 159 160 ip4a="192.0.2.1" 161 ip4b="192.0.2.2" 162 plen=29 163 src_ip="192.0.2.3" 164 165 script_name="../common/sender.py" 166 167 epair=$(vnet_mkepair) 168 ifconfig ${epair}a up 169 ifconfig ${epair}a inet ${ip4a}/${plen} 170 171 jname="v4t-fwd_ip_icmp_iface_slow_success" 172 vnet_mkjail ${jname} ${epair}b 173 jexec ${jname} ifconfig ${epair}b up 174 jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen} 175 176 # Get router ip/mac 177 jail_ip=${ip4b} 178 jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'` 179 180 our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'` 181 182 jexec ${jname} sysctl net.inet.ip.forwarding=1 183 # As we're doing router-on-the-stick, turn sending IP redirects off: 184 jexec ${jname} sysctl net.inet.ip.redirect=0 185 186 # Generate packet with options to force slow-path 187 atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \ 188 --test_name fwd_ip_icmp_slow \ 189 --smac ${our_mac} --dmac ${jail_mac} \ 190 --sip ${src_ip} --dip ${ip4a} \ 191 --iface ${epair}a 192 193 # check counters are valid 194 atf_check -o match:'1 packet forwarded \(0 packets fast forwarded\)' jexec ${jname} netstat -sp ip 195} 196 197fwd_ip_icmp_iface_slow_success_cleanup() { 198 199 vnet_cleanup 200} 201 202atf_test_case "fwd_ip_icmp_gw_slow_success" "cleanup" 203fwd_ip_icmp_gw_slow_success_head() { 204 205 atf_set descr 'Test valid IPv4 on-stick "slow" forwarding to gw' 206 atf_set require.user root 207 atf_set require.progs scapy 208} 209 210fwd_ip_icmp_gw_slow_success_body() { 211 212 vnet_init 213 214 ip4a="192.0.2.1" 215 ip4b="192.0.2.2" 216 plen=29 217 src_ip="192.0.2.3" 218 dst_ip="192.0.2.4" 219 220 script_name="../common/sender.py" 221 222 epair=$(vnet_mkepair) 223 ifconfig ${epair}a up 224 ifconfig ${epair}a inet ${ip4a}/${plen} 225 226 jname="v4t-fwd_ip_icmp_gw_slow_success" 227 vnet_mkjail ${jname} ${epair}b 228 jexec ${jname} ifconfig ${epair}b up 229 jexec ${jname} ifconfig ${epair}b inet ${ip4b}/${plen} 230 231 # Get router ip/mac 232 jail_ip=${ip4b} 233 jail_mac=`jexec ${jname} ifconfig ${epair}b ether | awk '$1~/ether/{print$2}'` 234 235 our_mac=`ifconfig ${epair}a ether | awk '$1~/ether/{print$2}'` 236 237 jexec ${jname} sysctl net.inet.ip.forwarding=1 238 # As we're doing router-on-the-stick, turn sending IP redirects off: 239 jexec ${jname} sysctl net.inet.ip.redirect=0 240 241 # Add host route 242 jexec ${jname} route -4 add -host ${dst_ip} ${ip4a} 243 244 # echo "LOCAL: ${local_ip} ${local_mac}" 245 # echo "REMOTE: ${remote_rtr_ip} ${remote_rtr_mac}" 246 247 atf_check -s exit:0 $(atf_get_srcdir)/${script_name} \ 248 --test_name fwd_ip_icmp_fast \ 249 --smac ${our_mac} --dmac ${jail_mac} \ 250 --sip ${src_ip} --dip ${dst_ip} \ 251 --iface ${epair}a 252 253 # check counters are valid 254 atf_check -o match:'1 packet forwarded \(1 packet fast forwarded\)' jexec ${jname} netstat -sp ip 255} 256 257fwd_ip_icmp_gw_slow_success_cleanup() { 258 259 vnet_cleanup 260} 261 262atf_test_case "fwd_ip_blackhole" "cleanup" 263fwd_ip_blackhole_head() { 264 265 atf_set descr 'Test blackhole routes' 266 atf_set require.user root 267} 268 269fwd_ip_blackhole_body() { 270 jname="v4t-fwd_ip_blackhole" 271 272 vnet_init 273 274 epair=$(vnet_mkepair) 275 epair_out=$(vnet_mkepair) 276 277 ifconfig ${epair}a 192.0.2.2/24 up 278 279 vnet_mkjail ${jname} ${epair}b ${epair_out}b 280 jexec ${jname} ifconfig lo0 127.0.0.1/8 up 281 jexec ${jname} ifconfig ${epair}b 192.0.2.1/24 up 282 jexec ${jname} ifconfig ${epair_out}b 198.51.100.1/24 up 283 jexec ${jname} sysctl net.inet.ip.forwarding=1 284 285 route add default 192.0.2.1 286 287 atf_check -s exit:2 -o ignore \ 288 ping -c 1 -t 1 198.51.100.2 289 atf_check -s exit:0 -o match:"0 packets not forwardable" \ 290 jexec ${jname} netstat -s -p ip 291 292 # Create blackhole route 293 jexec ${jname} /sbin/route add 198.51.100.2 -blackhole -fib 0 294 jexec ${jname} netstat -rn 295 296 # Include an IP option to ensure slow path 297 atf_check -s exit:2 -o ignore \ 298 ping -c 1 -t 1 -R 198.51.100.2 299 atf_check -s exit:0 -o match:"1 packet not forwardable" \ 300 jexec ${jname} netstat -s -p ip 301 302 # Now try via the fast path 303 atf_check -s exit:2 -o ignore \ 304 ping -c 1 -t 1 198.51.100.2 305 atf_check -s exit:0 -o match:"2 packets not forwardable" \ 306 jexec ${jname} netstat -s -p ip 307} 308 309fwd_ip_blackhole_cleanup() { 310 311 vnet_cleanup 312} 313 314atf_init_test_cases() 315{ 316 317 atf_add_test_case "fwd_ip_icmp_iface_fast_success" 318 atf_add_test_case "fwd_ip_icmp_gw_fast_success" 319 atf_add_test_case "fwd_ip_icmp_iface_slow_success" 320 atf_add_test_case "fwd_ip_icmp_gw_slow_success" 321 atf_add_test_case "fwd_ip_blackhole" 322} 323 324# end 325 326