netif-emulab.in 8.9 KB
Newer Older
1
#!/bin/sh
Mike Hibler's avatar
Mike Hibler committed
2
#
3
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
#
Mike Hibler's avatar
Mike Hibler committed
24 25 26 27 28 29 30 31
# Emulab version of netif to DHCP on all interfaces simultaneously.
# Runs before the standard netif, and effectively neuters that script.
# Note the dependencies below.  Every script that declares that it must run
# BEFORE netif is listed as a REQUIRE here so that we are properly ordered
# w.r.t. those scripts.
#

# PROVIDE: netif-emulab
32 33
# REQUIRE: atm1 FILESYSTEMS serial sppp sysctl
# REQUIRE: ipfilter ipfs netoptions
Mike Hibler's avatar
Mike Hibler committed
34
# BEFORE: netif
35
# KEYWORD: nojailvnet
Mike Hibler's avatar
Mike Hibler committed
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

. /etc/rc.subr
. /etc/network.subr

name="netif-emulab"
start_cmd="cnet_start"
stop_cmd="cnet_stop"
_cmdifn=

# some emulab paths
ELAB_LOGDIR=@CLIENT_VARDIR@/logs
ELAB_BOOTDIR=@CLIENT_VARDIR@/boot

# XXX accomodation for BSD-based frisbee MFS
if [ ! -d "$ELAB_BOOTDIR" ]; then
	if [ -r /etc/emulab/paths.sh ]; then
		. /etc/emulab/paths.sh
		ELAB_LOGDIR=$LOGDIR
		ELAB_BOOTDIR=$BOOTDIR
	else
		ELAB_LOGDIR=/etc/testbed
		ELAB_BOOTDIR=/etc/testbed
	fi
fi

61 62 63 64 65 66 67 68
#
# XXX hack for PRObE and nfe interfaces.
# The nfe driver apparently has issues and can fail to get an address.
# Gary Sandine found that taking the interface down and back up again can
# unstick things (if you are persistent enough).
#
cnet_nfe_hack()
{
69 70 71
	# XXX try for 10 minutes at fixed 30s intervals
	# XXX tried slowly increasing intervals, but didn't work
	for i in 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30; do
72 73 74
		echo "`date`: nfe_hack: taking interfaces down and up ..."
		for _if in $*; do
			ifconfig $_if down
75 76 77
		done
		sleep 2
		for _if in $*; do
78 79 80 81 82 83 84 85 86 87
			ifconfig $_if up
		done
		sleep $i
		if [ -e $ELAB_BOOTDIR/controlif ]; then
			echo "`date`: nfe_hack: worked!"
			break;
		fi
	done
}

88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
cnet_ibprobe()
{
    #
    # Handle Mellanox VPI cards: put them in auto mode.
    #
    if sysctl -q sys.class.infiniband_verbs.abi_version >/dev/null; then
	sleep 2
	if sysctl -q sys.device.mlx4_core0.mlx4_port1; then
	    echo "Putting Mellanox cards in auto mode..."
	    sysctl sys.device.mlx4_core0.mlx4_port1=auto
	    if sysctl -q sys.device.mlx4_core0.mlx4_port2; then
		sysctl sys.device.mlx4_core0.mlx4_port2=auto
	    fi
	    sleep 2
	fi
    fi
}

Mike Hibler's avatar
Mike Hibler committed
106 107 108 109 110 111 112 113 114 115 116
# this is a separate function so we can redirect all the output below
cnet_dhcp()
{
	#
	# Argh! FreeBSD >= 6 dhclient also allows only a single interface
	# to be specified.  I tried to make this work by launching multiple,
	# simultaneous dhclients, but that caused EEPROM read failures on
	# em devices.  So we will use the "pure" port version if it is
	# installed.
	#
	if [ -x /usr/local/sbin/dhclient ]; then
117
	    echo "`date`: Using dhclient port..."
Mike Hibler's avatar
Mike Hibler committed
118 119
	    dhclient_program="/usr/local/sbin/dhclient"
	    ${dhclient_program} ${dhclient_flags} $*
120
	    echo "`date`: $dhclient_program returned $?"
Mike Hibler's avatar
Mike Hibler committed
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
	else
	    echo "Using default dhclient..."

	    #
	    # Argh redux! FreeBSD >= 6 has rewritten dhclient and it no longer
	    # takes the -i option.  So we remove that option here.
	    #
	    dhclient_flags=`echo $dhclient_flags | sed -e 's/-i [0-9][0-9]*//'`

	    for _if in $*; do
		${dhclient_program} ${dhclient_flags} -b $_if
	    done
	    wait
	fi
}

cnet_start()
{
139 140
	_nfe=""

141 142
	cnet_ibprobe >>$ELAB_LOGDIR/netif-emulab.log 2>&1

Mike Hibler's avatar
Mike Hibler committed
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
	rm -f $ELAB_BOOTDIR/controlif

	#
	# Find all the relevant networks IFs.
	# Don't do loopback, funky tunnel devices
	# (e.g., IP-over-string-and-cans).
	#
	# At Utah Emulab we also exclude wireless interfaces as our
	# wireless machines are in a production ether and might get
	# an answer!
	#
	_ifs=""
	network_interfaces=`ifconfig -l | sed -e 's/lo0//'`
	for _if in $network_interfaces; do
	case $_if in
158
	lo*|gif*|faith*|tun*|plip*|usbus*|ipfw*)
Mike Hibler's avatar
Mike Hibler committed
159
		;;
160 161
	# XXX skip IPoIB
	ib[0-9])
162
		;;
Mike Hibler's avatar
Mike Hibler committed
163
	# XXX skip Intel 10Gb for now; they require huge numbers of mbufs
Mike Hibler's avatar
Mike Hibler committed
164
	ix[0-9]|ixl[0-9])
Mike Hibler's avatar
Mike Hibler committed
165
		;;
Mike Hibler's avatar
Mike Hibler committed
166 167
	ath*)
		;;
168 169 170 171
	nfe*)
		_nfe="$_nfe $_if"
		_ifs="$_ifs $_if"
		;;
Mike Hibler's avatar
Mike Hibler committed
172 173 174 175 176 177
	*)
		_ifs="$_ifs $_if"
		;;
	esac
	done

178 179
	#
	# XXX yow! If we don't come up with anything, we have to reconsider
180 181
	# some of those interface types we skipped:
	#  ix    because Clemson has an ix control network,
182 183 184 185
	#
	if [ -z "$_ifs" ]; then
	    for _if in $network_interfaces; do
	    case $_if in
186
	    ix[01])
187 188 189 190 191 192 193 194
		_ifs="$_ifs $_if"
		;;
	    *)
		;;
	    esac
	    done
	fi

Mike Hibler's avatar
Mike Hibler committed
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	# 
	# For the widearea case: decide if we want static or dynamic 
	# network configuration based on a config file.
	# XXX: should try to look on other media as well, instead of just
	# the boot dongle.
	#
	WACONFIG=/etc/emulab/waconfig
	if [ -e "$WACONFIG" ]; then
	        # key=val pairs become shell vars
		. "$WACONFIG"

		echo "Found Emulab widearea config info..."

		if [ "$WA_BOOTMETHOD" = "static" -a "$WA_MAC" != "" ]; then 
			# try to find an iface matching WA_MAC
			cnetif=""
			for _if in $network_interfaces; do
			        mac=`ifconfig $_if | grep ether | sed -e 's/[[:space:]]*ether[[:space:]]*//'`
				echo "$mac" | grep -i "$WA_MAC"
				if [ "$?" = "0" ]; then
				        cnetif="$_if"
				        break
				fi
			done

			if [ "$cnetif" = "" ]; then
			        echo -n "Could not find iface with "
				echo "$WA_MAC; trying DHCP!"
			        WA_BOOTMETHOD="dhcp"
			elif [ "$WA_HOSTNAME" = "" \
			        -o "$WA_DOMAIN" = "" \
			        -o "$WA_IP_ADDR" = "" \
			        -o "$WA_IP_NETMASK" = "" \
			        -o "$WA_IP_GATEWAY" = "" \
			        -o "$WA_IP_DNS1" = ""  ]; then
				echo -n "Missing static IP config "
				echo "vars; trying DHCP!"
				WA_BOOTMETHOD="dhcp"
			fi
		fi
	else
		WA_BOOTMETHOD="dhcp"
	fi

239 240 241 242 243 244 245
	#
	# Let's always bring up lo0 first.
	# Needed for the static configuration case (else clause).
	# Also needed for newer dhclients which need some interface to bind to.
	#
	ifconfig lo0 inet 127.0.0.1 up

Mike Hibler's avatar
Mike Hibler committed
246 247 248 249 250 251 252
	if [ "$WA_BOOTMETHOD" = "dhcp" ]; then
	        #
	        # use good ol' Emulab dhcp!
		#
		echo "Emulab looking for control net among: $_ifs ..."
		cnet_dhcp $_ifs >$ELAB_LOGDIR/netif-emulab.log 2>&1
		if [ -e $ELAB_BOOTDIR/controlif ]; then
253 254
		    _cif=`cat $ELAB_BOOTDIR/controlif`
		    echo "Emulab control net is $_cif"
Mike Hibler's avatar
Mike Hibler committed
255
		else
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
		    #
		    # XXX hack for nfe device on PRObE nodes. The PRObE
		    # nfe interfaces can get hung, but a down/up seems to
		    # get things moving again. The reset is done in
		    # dhclient-enter-hooks, we just wait for it to take
		    # effect here.
		    #
		    if [ -n "$_nfe" ]; then
			echo "Engaging control net nfe hack on: $_nfe ..."
			cnet_nfe_hack $_nfe >>$ELAB_LOGDIR/netif-emulab.log 2>&1
		    fi
		    if [ -e $ELAB_BOOTDIR/controlif ]; then
			_cif=`cat $ELAB_BOOTDIR/controlif`
			echo "Emulab control net is $_cif"
		    else
Mike Hibler's avatar
Mike Hibler committed
271
			echo "*** No Emulab control net found!"
272
		    fi
Mike Hibler's avatar
Mike Hibler committed
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
		fi
	else
		#
		# configure according to static WA_X vars:
		#
		echo "Emulab statically configuring control net on $cnetif ..."
		ifconfig "$cnetif" inet "$WA_IP_ADDR" netmask "$WA_IP_NETMASK" up
		route add default "$WA_IP_GATEWAY"

		# setup resolv.conf
		echo "search $WA_DOMAIN" > /etc/resolv.conf
		echo "nameserver $WA_IP_DNS1" >> /etc/resolv.conf
		if [ "$WA_IP_DNS2" != "" ]; then
			echo "nameserver $WA_IP_DNS2" >> /etc/resolv.conf
		fi

		# set hostname
		hosts_str="$WA_HOSTNAME"
                echo "$WA_HOSTNAME" | grep -q \\.
                if [ $? = 0 ]; then
                        hostname "$WA_HOSTNAME"
                else
                        hostname "${WA_HOSTNAME}.${WA_DOMAIN}"
			hosts_str="${WA_HOSTNAME}.${WA_DOMAIN} ${hosts_str}"
                fi

		# setup hosts file
		echo "$WA_IP_ADDR ${hosts_str}" >> /etc/hosts

		# setup a few necessary emulab files...
		echo "$cnetif" > $ELAB_BOOTDIR/controlif
		if [ -e "/etc/emulab/bossnode" ]; then
			bossnode=`cat /etc/emulab/bossnode`
			bossip=`host -t A "$bossnode"`
			retval="$?"
			i=0
			while [ "$retval" != "0" -a $i -lt 180 ]; do
				echo "Failed to resolve boss ($bossnode)!"
				sleep 5
				i=`expr $i + 1`
				bossip=`host -t A "$bossnode"`
				retval="$?"
			done
			if [ "$retval" = "0" ]; then
				echo "Resolved boss ($bossnode) to $bossip."
				echo `echo "$bossip" | sed -n -e 's/.*has address\s*\(.*\)/\1/p'` \
					> $ELAB_BOOTDIR/bossip
		        fi
		fi
		echo "$WA_HOSTNAME" > $ELAB_BOOTDIR/realname
		echo "$WA_IP_GATEWAY" > $ELAB_BOOTDIR/routerip
		echo "$WA_IP_ADDR" > $ELAB_BOOTDIR/myip
		echo "$WA_IP_NETMASK" > $ELAB_BOOTDIR/mynetmask
	fi
}

cnet_stop()
{
	rm -f $ELAB_BOOTDIR/controlif
}

load_rc_config $name
run_rc_command $*