1#- 2# SPDX-License-Identifier: BSD-2-Clause 3# 4# Copyright (c) 2019 Ahsan Barkati 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# 28 29. $(atf_get_srcdir)/utils.subr 30. $(atf_get_srcdir)/runner.subr 31 32basic_head() 33{ 34 atf_set descr 'Basic IPv4 NAT test' 35 atf_set require.user root 36} 37 38basic_body() 39{ 40 firewall=$1 41 firewall_init $firewall 42 nat_init $firewall 43 44 epair_host_nat=$(vnet_mkepair) 45 epair_client1_nat=$(vnet_mkepair) 46 epair_client2_nat=$(vnet_mkepair) 47 48 vnet_mkjail nat ${epair_host_nat}b ${epair_client1_nat}a ${epair_client2_nat}a 49 vnet_mkjail client1 ${epair_client1_nat}b 50 vnet_mkjail client2 ${epair_client2_nat}b 51 52 ifconfig ${epair_host_nat}a 198.51.100.2/24 up 53 jexec nat ifconfig ${epair_host_nat}b 198.51.100.1/24 up 54 55 jexec nat ifconfig ${epair_client1_nat}a 192.0.2.1/24 up 56 jexec client1 ifconfig ${epair_client1_nat}b 192.0.2.2/24 up 57 58 jexec nat ifconfig ${epair_client2_nat}a 192.0.3.1/24 up 59 jexec client2 ifconfig ${epair_client2_nat}b 192.0.3.2/24 up 60 61 jexec nat sysctl net.inet.ip.forwarding=1 62 63 jexec client1 route add -net 198.51.100.0/24 192.0.2.1 64 jexec client2 route add -net 198.51.100.0/24 192.0.3.1 65 66 # ping fails without NAT configuration 67 atf_check -s exit:2 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 68 atf_check -s exit:2 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 69 70 firewall_config nat ${firewall} \ 71 "pf" \ 72 "nat pass on ${epair_host_nat}b inet from any to any -> (${epair_host_nat}b)" \ 73 "ipfw" \ 74 "ipfw -q nat 123 config if ${epair_host_nat}b" \ 75 "ipfw -q add 1000 nat 123 all from any to any" \ 76 "ipfnat" \ 77 "map ${epair_host_nat}b 192.0.3.0/24 -> 0/32" \ 78 "map ${epair_host_nat}b 192.0.2.0/24 -> 0/32" \ 79 80 81 # ping is successful now 82 atf_check -s exit:0 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 83 atf_check -s exit:0 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 84 85} 86 87basic_cleanup() 88{ 89 firewall=$1 90 firewall_cleanup $firewall 91} 92 93userspace_nat_head() 94{ 95 atf_set descr 'Nat test for ipfw using userspace natd' 96 atf_set require.user root 97} 98userspace_nat_body() 99{ 100 firewall=$1 101 firewall_init $firewall 102 103 if ! kldstat -q -m ipdivert; then 104 atf_skip "This test requires ipdivert module loaded" 105 fi 106 107 epair_host_nat=$(vnet_mkepair) 108 epair_client1_nat=$(vnet_mkepair) 109 epair_client2_nat=$(vnet_mkepair) 110 111 vnet_mkjail nat ${epair_host_nat}b ${epair_client1_nat}a ${epair_client2_nat}a 112 vnet_mkjail client1 ${epair_client1_nat}b 113 vnet_mkjail client2 ${epair_client2_nat}b 114 115 ifconfig ${epair_host_nat}a 198.51.100.2/24 up 116 jexec nat ifconfig ${epair_host_nat}b 198.51.100.1/24 up 117 118 jexec nat ifconfig ${epair_client1_nat}a 192.0.2.1/24 up 119 jexec client1 ifconfig ${epair_client1_nat}b 192.0.2.2/24 up 120 121 jexec nat ifconfig ${epair_client2_nat}a 192.0.3.1/24 up 122 jexec client2 ifconfig ${epair_client2_nat}b 192.0.3.2/24 up 123 124 jexec nat sysctl net.inet.ip.forwarding=1 125 126 jexec client1 route add -net 198.51.100.0/24 192.0.2.1 127 jexec client2 route add -net 198.51.100.0/24 192.0.3.1 128 # Test the userspace NAT of ipfw 129 # ping fails without NAT configuration 130 atf_check -s exit:2 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 131 atf_check -s exit:2 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 132 133 firewall_config nat ${firewall} \ 134 "ipfw" \ 135 "natd -interface ${epair_host_nat}b" \ 136 "ipfw -q add divert natd all from any to any via ${epair_host_nat}b" \ 137 138 # ping is successful now 139 atf_check -s exit:0 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 140 atf_check -s exit:0 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 141} 142 143userspace_nat_cleanup() 144{ 145 firewall=$1 146 firewall_cleanup $firewall 147} 148 149common_cgn() { 150 firewall=$1 151 portalias=$2 152 firewall_init $firewall 153 nat_init $firewall 154 155 epair_host_nat=$(vnet_mkepair) 156 epair_client1_nat=$(vnet_mkepair) 157 epair_client2_nat=$(vnet_mkepair) 158 159 vnet_mkjail nat ${epair_host_nat}b ${epair_client1_nat}a ${epair_client2_nat}a 160 vnet_mkjail client1 ${epair_client1_nat}b 161 vnet_mkjail client2 ${epair_client2_nat}b 162 163 ifconfig ${epair_host_nat}a 198.51.100.2/24 up 164 jexec nat ifconfig ${epair_host_nat}b 198.51.100.1/24 up 165 166 jexec nat ifconfig ${epair_client1_nat}a 100.64.0.1/24 up 167 jexec client1 ifconfig ${epair_client1_nat}b 100.64.0.2/24 up 168 169 jexec nat ifconfig ${epair_client2_nat}a 100.64.1.1/24 up 170 jexec client2 ifconfig ${epair_client2_nat}b 100.64.1.2/24 up 171 172 jexec nat sysctl net.inet.ip.forwarding=1 173 174 jexec client1 route add -net 198.51.100.0/24 100.64.0.1 175 jexec client2 route add -net 198.51.100.0/24 100.64.1.1 176 177 # ping fails without NAT configuration 178 atf_check -s exit:2 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 179 atf_check -s exit:2 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 180 181 if [[ $portalias ]]; then 182 firewall_config nat $firewall \ 183 "ipfw" \ 184 "ipfw -q nat 123 config if ${epair_host_nat}b unreg_cgn port_alias 2000-2999" \ 185 "ipfw -q nat 456 config if ${epair_host_nat}b unreg_cgn port_alias 3000-3999" \ 186 "ipfw -q add 1000 nat 123 all from any to 198.51.100.2 2000-2999 in via ${epair_host_nat}b" \ 187 "ipfw -q add 2000 nat 456 all from any to 198.51.100.2 3000-3999 in via ${epair_host_nat}b" \ 188 "ipfw -q add 3000 nat 123 all from 100.64.0.2 to any out via ${epair_host_nat}b" \ 189 "ipfw -q add 4000 nat 456 all from 100.64.1.2 to any out via ${epair_host_nat}b" 190 else 191 firewall_config nat $firewall \ 192 "ipfw" \ 193 "ipfw -q nat 123 config if ${epair_host_nat}b unreg_cgn" \ 194 "ipfw -q add 1000 nat 123 all from any to any" 195 fi 196 197 # ping is successful now 198 atf_check -s exit:0 -o ignore jexec client1 ping -t 1 -c 1 198.51.100.2 199 atf_check -s exit:0 -o ignore jexec client2 ping -t 1 -c 1 198.51.100.2 200 201 # if portalias, test a tcp server/client with nc 202 if [[ $portalias ]]; then 203 for inst in 1 2; do 204 daemon nc -p 198.51.100.2 7 205 atf_check -s exit:0 -o ignore jexec client$inst sh -c "echo | nc -N 198.51.100.2 7" 206 done 207 fi 208} 209 210cgn_head() 211{ 212 atf_set descr 'IPv4 CGN (RFC 6598) test' 213 atf_set require.user root 214} 215 216cgn_body() 217{ 218 common_cgn $1 false 219} 220 221cgn_cleanup() 222{ 223 firewall_cleanup ipfw 224} 225 226portalias_head() 227{ 228 atf_set descr 'IPv4 CGN (RFC 6598) port aliasing test' 229 atf_set require.user root 230} 231 232portalias_body() 233{ 234 common_cgn $1 true 235} 236 237portalias_cleanup() 238{ 239 firewall_cleanup ipfw 240} 241 242setup_tests \ 243 basic \ 244 pf \ 245 ipfw \ 246 ipfnat \ 247 userspace_nat \ 248 ipfw \ 249 cgn \ 250 ipfw \ 251 portalias \ 252 ipfw 253