1#!/usr/bin/env atf-sh 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright 2022 John-Mark Gurney 6# All rights reserved. 7# 8# Redistribution and use in source and binary forms, with or without 9# modification, are permitted provided that the following conditions are 10# met: 11# 12# * Redistributions of source code must retain the above copyright 13# notice, this list of conditions and the following disclaimer. 14# * Redistributions in binary form must reproduce the above copyright 15# notice, this list of conditions and the following disclaimer in the 16# documentation and/or other materials provided with the distribution. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30# 31# Run the tests: 32# make WITH_TESTS=yes -j 4 all install && kyua test -k /usr/tests/Kyuafile sbin/dhclient/pcp 33# 34# Output last run: 35# kyua report --verbose -r $(ls -tr ~/.kyua/store/results.*.db | tail -n 1) 36 37. $(atf_get_srcdir)/../../sys/common/vnet.subr 38 39generic_dhcp_cleanup() 40{ 41 42 # clean up programs 43 kill $(cat dhclient.test.pid) $(cat dhcpd.pid) 44 45 # clean up files 46 rm -f dhclient.dhcpd.conf lease.dhclient.test dhclient.test.pid 47 48 vnet_cleanup 49} 50 51atf_test_case normal cleanup 52normal_head() 53{ 54 atf_set descr 'test dhclient against a server' 55 atf_set require.user root 56 atf_set "require.progs" dhclient 57} 58 59normal_body() 60{ 61 dhcpd=$(which dhcpd) 62 63 if ! [ -x "$dhcpd" ]; then 64 atf_skip "ISC dhcp server (isc-dhcp44-server) not installed" 65 fi 66 67 vnet_init 68 69 epair=$(vnet_mkepair) 70 71 vnet_mkjail dhclient_normal_test ${epair}b 72 73 # Set IP on server iface 74 ifconfig ${epair}a 192.0.2.2/24 up 75 76 # Create dhcp server config 77 cat > dhclient.dhcpd.conf << EOF 78default-lease-time 36000; 79max-lease-time 86400; 80authoritative; 81subnet 192.0.2.0 netmask 255.255.255.0 { 82 range 192.0.2.10 192.0.2.10; 83 option routers 192.0.2.2; 84 option domain-name-servers 192.0.2.2; 85} 86EOF 87 88 # Start dhcp server 89 touch dhcpd.leases.conf 90 atf_check -e ignore ${dhcpd} -cf ./dhclient.dhcpd.conf -lf ./dhcpd.leases.conf -pf ./dhcpd.pid ${epair}a 91 92 # Expect that we get an IP assigned 93 atf_check -e match:'DHCPACK from 192.0.2.2' jexec dhclient_normal_test dhclient -c /dev/null -l ./lease.dhclient.test -p ./dhclient.test.pid ${epair}b 94 95 # And it's the correct one 96 atf_check -o match:'inet 192.0.2.10' jexec dhclient_normal_test ifconfig ${epair}b 97 98} 99 100normal_cleanup() 101{ 102 103 generic_dhcp_cleanup 104} 105 106atf_test_case pcp cleanup 107pcp_head() 108{ 109 atf_set descr 'test dhclient on pcp interface' 110 atf_set require.user root 111 atf_set "require.progs" dhclient 112} 113 114pcp_body() 115{ 116 dhcpd=$(which dhcpd) 117 118 if ! [ -x "$dhcpd" ]; then 119 atf_skip "ISC dhcp server (isc-dhcp44-server) not installed" 120 fi 121 122 vnet_init 123 124 epair=$(vnet_mkepair) 125 126 # Server side needs to be up to pass packets 127 ifconfig ${epair}a up 128 129 # Make sure necessary netgraph modules are loaded 130 kldstat -q -n ng_ether || kldload ng_ether 131 kldstat -q -n ng_iface || kldload ng_iface 132 kldstat -q -n ng_vlan || kldload ng_vlan 133 134 # create vlan, and attach epair to it (has incoming/outgoing vlan 135 # 0 tagged frames) 136 ngctl mkpeer ${epair}a: vlan lower downstream 137 138 # create new interface on other side of vlan (untagged/pcp) 139 ngctl mkpeer ${epair}a:lower. eiface vlan0 ether 140 141 # get the interface created 142 ngiface=$(ngctl show ${epair}a:lower.vlan0 | head -n 1 | awk '{ print $2}') 143 144 # schedule it for clean up 145 echo ${ngiface} >> ngctl.shutdown 146 147 # set the filter on it 148 ngctl msg ${epair}a:lower. 'addfilter { vlan=0 hook="vlan0" }' 149 150 vnet_mkjail dhclient_pcp_test ${epair}b 151 152 # Set IP on server iface 153 ifconfig ${ngiface} up 192.0.2.2/24 154 155 # Set pcp in jail 156 jexec dhclient_pcp_test ifconfig ${epair}b pcp 0 up 157 158 # Create dhcp server config 159 cat > dhclient.dhcpd.conf << EOF 160default-lease-time 36000; 161max-lease-time 86400; 162authoritative; 163subnet 192.0.2.0 netmask 255.255.255.0 { 164 range 192.0.2.10 192.0.2.10; 165 option routers 192.0.2.2; 166 option domain-name-servers 192.0.2.2; 167} 168EOF 169 170 # Start dhcp server 171 touch dhcpd.leases.conf 172 atf_check -e ignore ${dhcpd} -cf ./dhclient.dhcpd.conf -lf ./dhcpd.leases.conf -pf ./dhcpd.pid ${ngiface} 173 174 # Expect that we get an IP assigned 175 atf_check -e match:'DHCPACK from 192.0.2.2' jexec dhclient_pcp_test dhclient -c /dev/null -l ./lease.dhclient.test -p ./dhclient.test.pid ${epair}b 176 177 # And it's the correct one 178 atf_check -o match:'inet 192.0.2.10' jexec dhclient_pcp_test ifconfig ${epair}b 179} 180 181pcp_cleanup() 182{ 183 184 generic_dhcp_cleanup 185 186 # Clean up netgraph nodes 187 for i in $(cat ngctl.shutdown); do 188 ngctl shutdown ${i}: 189 done 190 rm -f ngctl.shutdown 191} 192 193atf_init_test_cases() 194{ 195 atf_add_test_case normal 196 atf_add_test_case pcp 197} 198 199