Home | History | Annotate | Download | only in milestone
      1 #!/sbin/sh
      2 #
      3 # CDDL HEADER START
      4 #
      5 # The contents of this file are subject to the terms of the
      6 # Common Development and Distribution License (the "License").
      7 # You may not use this file except in compliance with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 #
     23 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24 # Use is subject to license terms.
     25 #
     26 # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
     27 # All rights reserved.
     28 #
     29 
     30 . /lib/svc/share/smf_include.sh
     31 . /lib/svc/share/net_include.sh
     32 
     33 #
     34 # In a shared-IP zone we need this service to be up, but all of the work
     35 # it tries to do is irrelevant (and will actually lead to the service 
     36 # failing if we try to do it), so just bail out. 
     37 # In the global zone and exclusive-IP zones we proceed.
     38 #
     39 smf_configure_ip || exit $SMF_EXIT_OK
     40 
     41 # Make sure that the libraries essential to this stage of booting can be found.
     42 LD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH
     43 
     44 smf_netstrategy
     45 
     46 if smf_is_globalzone; then
     47 	net_reconfigure || exit $SMF_EXIT_ERR_CONFIG
     48 
     49 	# Update PVID on interfaces configured with VLAN 1
     50 	update_pvid
     51 
     52 	# 
     53 	# Upgrade handling. The upgrade file consists of a series of dladm(1M)
     54 	# commands. Note that after we are done, we cannot rename the upgrade
     55 	# script file as the file system is still read-only at this point.
     56 	# Defer this to the manifest-import service.
     57 	#
     58 	upgrade_script=/var/svc/profile/upgrade_datalink
     59 	if [ -f "${upgrade_script}" ]; then 
     60 		. "${upgrade_script}"
     61 	fi
     62 
     63 	#
     64 	# Bring up simnets, link aggregations and initialize security objects.
     65 	# Note that link property initialization is deferred until after
     66 	# IP interfaces are plumbed to ensure that the links will not
     67 	# be unloaded (and the property settings lost). We should bring
     68 	# up simnets prior to VLANs/Aggrs to enable creation of VLANs/Aggrs
     69 	# over simnets.
     70 	#
     71 	/sbin/dladm up-simnet
     72 	/sbin/dladm up-aggr
     73 	/sbin/dladm up-vlan
     74 	/sbin/dladm init-secobj
     75 	#
     76 	# Bring up VNICs
     77 	#
     78 	/sbin/dladm up-vnic
     79 	#
     80 	# Create flows via flowadm.
     81 	#
     82 	/sbin/flowadm init-flow
     83 fi
     84 
     85 #
     86 # If the system was net booted by DHCP, hand DHCP management off to the
     87 # DHCP agent (ifconfig communicates to the DHCP agent through the
     88 # loopback interface).
     89 #
     90 if [ -n "$_INIT_NET_IF" -a "$_INIT_NET_STRATEGY" = "dhcp" ]; then
     91 	/sbin/dhcpagent -a
     92 fi
     93 
     94 #
     95 # The network initialization is done early to support diskless and
     96 # dataless configurations.  For IPv4 interfaces that were configured by
     97 # the kernel (e.g.  those on diskless machines) and not configured by
     98 # DHCP, reset the netmask using the local "/etc/netmasks" file if one
     99 # exists, and then reset the broadcast address based on the netmask.
    100 #
    101 /sbin/ifconfig -auD4 netmask + broadcast +
    102 
    103 is_iptun ()
    104 {
    105 	intf=$1
    106 	# Is this a persistent IP tunnel link?
    107 	/sbin/dladm show-iptun -P $intf > /dev/null 2>&1
    108 	if [ $? -eq 0 ]; then
    109 		return 0
    110 	fi
    111 	# Is this an implicit IP tunnel (i.e., ip.tun0)
    112 	ORIGIFS="$IFS"
    113 	IFS="$IFS."
    114 	set -- $intf
    115 	IFS="$ORIGIFS"
    116 	if [ $# -eq 2 -a \( "$1" = "ip" -o "$1" = "ip6" \) ]; then
    117 		#
    118 		# It looks like one, but another type of link might be
    119 		# using a name that looks like an implicit IP tunnel.
    120 		# If dladm show-link -P finds it, then it's not an IP
    121 		# tunnel.
    122 		#
    123 		/sbin/dladm show-link -Pp $intf > /dev/null 2>&1
    124 		if [ $? -eq 0 ]; then
    125 			return 1
    126 		else
    127 			return 0
    128 		fi
    129 	fi
    130 	return 1
    131 }
    132 
    133 #
    134 # All the IPv4 and IPv6 interfaces are plumbed before doing any
    135 # interface configuration.  This prevents errors from plumb failures
    136 # getting mixed in with the configured interface lists that the script
    137 # outputs.
    138 #
    139 
    140 #
    141 # Get the list of IPv4 interfaces to configure by breaking
    142 # /etc/hostname.* into separate args by using "." as a shell separator
    143 # character.
    144 #
    145 interface_names="`echo /etc/hostname.*[0-9] 2>/dev/null`"
    146 if [ "$interface_names" != "/etc/hostname.*[0-9]" ]; then
    147 	ORIGIFS="$IFS"
    148 	IFS="$IFS."
    149 	set -- $interface_names
    150 	IFS="$ORIGIFS"
    151 	while [ $# -ge 2 ]; do
    152 		shift
    153 		intf_name=$1
    154 		while [ $# -gt 1 -a "$2" != "/etc/hostname" ]; do
    155 			intf_name="$intf_name.$2"
    156 			shift
    157 		done
    158 		shift
    159 
    160 		# skip IP tunnel interfaces plumbed by net-iptun.
    161 		if is_iptun $intf_name; then
    162 			continue
    163 		fi
    164 
    165 	        read one rest < /etc/hostname.$intf_name
    166 		if [ "$one" = ipmp ]; then
    167 			ipmp_list="$ipmp_list $intf_name"
    168 		else
    169 			inet_list="$inet_list $intf_name"
    170 		fi
    171 	done
    172 fi
    173 
    174 #
    175 # Get the list of IPv6 interfaces to configure by breaking
    176 # /etc/hostname6.* into separate args by using "." as a shell separator
    177 # character.
    178 #
    179 interface_names="`echo /etc/hostname6.*[0-9] 2>/dev/null`"
    180 if [ "$interface_names" != "/etc/hostname6.*[0-9]" ]; then
    181 	ORIGIFS="$IFS"
    182 	IFS="$IFS."
    183 	set -- $interface_names
    184 	IFS="$ORIGIFS"
    185 	while [ $# -ge 2 ]; do
    186 		shift
    187 		intf_name=$1
    188 		while [ $# -gt 1 -a "$2" != "/etc/hostname6" ]; do
    189 			intf_name="$intf_name.$2"
    190 			shift
    191 		done
    192 		shift
    193 
    194 		# skip IP tunnel interfaces plumbed by net-iptun.
    195 		if is_iptun $intf_name; then
    196 			continue
    197 		fi
    198 
    199 	        read one rest < /etc/hostname6.$intf_name
    200 		if [ "$one" = ipmp ]; then
    201 			ipmp6_list="$ipmp6_list $intf_name"
    202 		else
    203 			inet6_list="$inet6_list $intf_name"
    204 		fi
    205 	done
    206 fi
    207 
    208 #
    209 # Create all of the IPv4 IPMP interfaces.
    210 #
    211 if [ -n "$ipmp_list" ]; then
    212 	set -- $ipmp_list
    213 	while [ $# -gt 0 ]; do
    214 	    	if /sbin/ifconfig $1 ipmp; then
    215 			ipmp_created="$ipmp_created $1"
    216 		else
    217 			ipmp_failed="$ipmp_failed $1"
    218 		fi	
    219 		shift
    220 	done
    221 	[ -n "$ipmp_failed" ] && warn_failed_ifs "create IPv4 IPMP" \
    222 	    "$ipmp_failed"
    223 fi
    224 
    225 #
    226 # Step through the IPv4 interface list and try to plumb every interface.
    227 # Generate list of plumbed and failed IPv4 interfaces.
    228 #
    229 if [ -n "$inet_list" ]; then
    230 	set -- $inet_list
    231 	while [ $# -gt 0 ]; do
    232 		/sbin/ifconfig $1 plumb
    233 		if /sbin/ifconfig $1 inet >/dev/null 2>&1; then
    234 			inet_plumbed="$inet_plumbed $1"
    235 		else
    236 			inet_failed="$inet_failed $1"
    237 		fi
    238 		shift
    239 	done
    240 	[ -n "$inet_failed" ] && warn_failed_ifs "plumb IPv4" "$inet_failed"
    241 fi
    242 
    243 # Run autoconf to connect to a WLAN if the interface is a wireless one
    244 if [ -x /sbin/wificonfig -a -n "$inet_plumbed" ]; then
    245 	set -- $inet_plumbed
    246 	while [ $# -gt 0 ]; do
    247 			if [ -r /dev/wifi/$1 ]; then
    248 				/sbin/wificonfig -i $1 startconf >/dev/null
    249 			fi
    250 		shift
    251 	done
    252 fi
    253 
    254 #
    255 # Step through the IPv6 interface list and plumb every interface.
    256 # Generate list of plumbed and failed IPv6 interfaces.  Each plumbed
    257 # interface will be brought up later, after processing any contents of
    258 # the /etc/hostname6.* file.
    259 #
    260 if [ -n "$inet6_list" ]; then
    261 	set -- $inet6_list
    262 	while [ $# -gt 0 ]; do
    263 		/sbin/ifconfig $1 inet6 plumb
    264 		if /sbin/ifconfig $1 inet6 >/dev/null 2>&1; then
    265 			inet6_plumbed="$inet6_plumbed $1"
    266 		else
    267 			inet6_failed="$inet6_failed $1"
    268 		fi
    269 		shift
    270 	done
    271 	[ -n "$inet6_failed" ] && warn_failed_ifs "plumb IPv6" "$inet6_failed"
    272 fi
    273 
    274 #
    275 # Create all of the IPv6 IPMP interfaces.
    276 #
    277 if [ -n "$ipmp6_list" ]; then
    278 	set -- $ipmp6_list
    279 	while [ $# -gt 0 ]; do
    280 	    	if /sbin/ifconfig $1 inet6 ipmp; then
    281 			ipmp6_created="$ipmp6_created $1"
    282 		else
    283 			ipmp6_failed="$ipmp6_failed $1"
    284  		fi
    285 		shift
    286 	done
    287 	[ -n "$ipmp6_failed" ] && warn_failed_ifs "create IPv6 IPMP" \
    288 	    "$ipmp6_failed"
    289 fi
    290 
    291 #
    292 # Process the /etc/hostname[6].* files for IPMP interfaces.  Processing these
    293 # before non-IPMP interfaces avoids accidental implicit IPMP group creation.
    294 #
    295 [ -n "$ipmp_created" ] && if_configure inet "IPMP" $ipmp_created
    296 [ -n "$ipmp6_created" ] && if_configure inet6 "IPMP" $ipmp6_created
    297 
    298 #
    299 # Process the /etc/hostname[6].* files for non-IPMP interfaces.
    300 #
    301 [ -n "$inet_plumbed" ] && if_configure inet "" $inet_plumbed
    302 [ -n "$inet6_plumbed" ] && if_configure inet6 "" $inet6_plumbed
    303 
    304 #
    305 # For the IPv4 and IPv6 interfaces that failed to plumb, find (or create)
    306 # IPMP meta-interfaces to host their data addresses.
    307 #
    308 [ -n "$inet_failed" ] && move_addresses inet
    309 [ -n "$inet6_failed" ] && move_addresses inet6
    310 
    311 # Run DHCP if requested. Skip boot-configured interface.
    312 interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`"
    313 if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then
    314 	#
    315 	# First find the primary interface. Default to the first
    316 	# interface if not specified. First primary interface found
    317 	# "wins". Use care not to "reconfigure" a net-booted interface
    318 	# configured using DHCP. Run through the list of interfaces
    319 	# again, this time trying DHCP.
    320 	#
    321 	i4d_fail=
    322 	firstif=
    323 	primary=
    324 	ORIGIFS="$IFS"
    325 	IFS="${IFS}."
    326 	set -- $interface_names
    327 
    328 	while [ $# -ge 2 ]; do
    329 		shift
    330 		[ -z "$firstif" ] && firstif=$1
    331 
    332 		for i in `shcat /etc/dhcp\.$1`; do
    333 			if [ "$i" = primary ]; then
    334 				primary=$1
    335 				break
    336 			fi
    337 		done
    338 
    339 		[ -n "$primary" ] && break
    340 		shift
    341 	done
    342 
    343 	[ -z "$primary" ] && primary="$firstif"
    344 	cmdline=`shcat /etc/dhcp\.${primary}`
    345 
    346 	if [ "$_INIT_NET_IF" != "$primary" ]; then
    347 		echo "starting DHCP on primary interface $primary"
    348 		/sbin/ifconfig $primary auto-dhcp primary $cmdline
    349 		# Exit code 4 means ifconfig timed out waiting for dhcpagent
    350 		[ $? != 0 ] && [ $? != 4 ] && i4d_fail="$i4d_fail $primary"
    351 	fi
    352 
    353 	set -- $interface_names
    354 
    355 	while [ $# -ge 2 ]; do
    356 		shift
    357 		cmdline=`shcat /etc/dhcp\.$1`
    358 		if [ "$1" != "$primary" -a \
    359 			"$1" != "$_INIT_NET_IF"  ]; then
    360 			echo "starting DHCP on interface $1"
    361 			/sbin/ifconfig $1 dhcp start wait 0 $cmdline
    362 			# Exit code can't be timeout when wait is 0
    363 			[ $? != 0 ] && i4d_fail="$i4d_fail $1"
    364 		fi
    365 		shift
    366 	done
    367 	IFS="$ORIGIFS"
    368 	unset ORIGIFS
    369 	[ -n "$i4d_fail" ] && warn_failed_ifs "configure IPv4 DHCP" "$i4d_fail"
    370 fi
    371 
    372 # In order to avoid bringing up the interfaces that have
    373 # intentionally been left down, perform RARP only if the system
    374 # has no configured hostname in /etc/nodename
    375 hostname="`shcat /etc/nodename 2>/dev/null`"
    376 if [ "$_INIT_NET_STRATEGY" = "rarp" -o -z "$hostname" ]; then
    377 	/sbin/ifconfig -adD4 auto-revarp netmask + broadcast + up
    378 fi
    379 
    380 #
    381 # If the /etc/defaultrouter file exists, process it now so that the next
    382 # stage of booting will have access to NFS.
    383 #
    384 if [ -f /etc/defaultrouter ]; then
    385 	while read router rubbish; do
    386 		case "$router" in
    387 			'#'* | '') ;;	#  Ignore comments, empty lines
    388 			*)	/sbin/route -n add default -gateway $router ;;
    389 		esac
    390 	done </etc/defaultrouter
    391 fi
    392 
    393 #
    394 # If we get here and were not asked to plumb any IPv4 interfaces, look
    395 # for boot properties that direct us.
    396 #
    397 # - The "network-interface" property is required and indicates the
    398 #   interface name.
    399 # - The "xpv-hcp" property, if present, is used by the hypervisor
    400 #   tools to indicate how the specified interface should be configured.
    401 #   Permitted values are "dhcp" and "off", where "off" indicates static
    402 #   IP configuration.
    403 #
    404 # In the case where "xpv-hcp" is set to "dhcp", no further properties
    405 # are required or examined.
    406 #
    407 # In the case where "xpv-hcp" is not present or set to "off", the
    408 # "host-ip" and "subnet-mask" properties are used to configure
    409 # the specified interface.  The "router-ip" property, if present,
    410 # is used to add a default route.
    411 #
    412 nic="`/sbin/devprop network-interface`"
    413 if smf_is_globalzone && [ -z "$inet_list" ] && [ -n "$nic" ]; then
    414 	hcp="`/sbin/devprop xpv-hcp`"
    415 	case "$hcp" in
    416 	"dhcp")
    417 		/sbin/ifconfig $nic plumb 2>/dev/null
    418 		[ -n "`/sbin/ifconfig $nic 2>/dev/null`" ] && (
    419 			# The interface is successfully plumbed, so
    420 			# modify "inet_list" to force the exit code
    421 			# checks to work.
    422 			inet_list=$nic;
    423 			# Given that this is the only IPv4 interface,
    424 			# we assert that it is primary.
    425 			echo "starting DHCP on primary interface $primary";
    426 			/sbin/ifconfig $nic auto-dhcp primary;
    427 			# Exit code 4 means ifconfig timed out waiting
    428 			# for dhcpagent
    429 			[ $? != 0 ] && [ $? != 4 ] && \
    430 			    i4d_fail="$i4d_fail $nic";
    431 		)
    432 		;;
    433 
    434 	"off"|"")
    435 		/sbin/devprop host-ip subnet-mask router-ip | (
    436 			read ip;
    437 			read mask;
    438 			read router;
    439 			[ -n "$ip" ] && [ -n "$mask" ] && \
    440 				/sbin/ifconfig $nic plumb 2>/dev/null
    441 			[ -n "`/sbin/ifconfig $nic 2>/dev/null`" ] && (
    442 				# The interface is successfully
    443 				# plumbed, so modify "inet_list" to
    444 				# force the exit code checks to work.
    445 				inet_list=$nic;
    446 				/sbin/ifconfig $nic  inet $ip \
    447 				    netmask $mask broadcast + up 2>/dev/null;
    448 				[ -n "$router" ] && route add \
    449 				    default $router 2>/dev/null;
    450 			)
    451 		)
    452 		;;
    453 	esac
    454 fi
    455 
    456 #
    457 # We tell smf this service is online if any of the following is true:
    458 # - no interfaces were configured for plumbing and no DHCP failures
    459 # - any non-loopback IPv4 interfaces are up and have a non-zero address
    460 # - there are any DHCP interfaces started
    461 # - any non-loopback IPv6 interfaces are up
    462 #
    463 # If we weren't asked to configure any interfaces, exit
    464 if [ -z "$inet_list" ] && [ -z "$inet6_list" ]; then
    465 	# Config error if DHCP was attempted without plumbed interfaces
    466 	[ -n "$i4d_fail" ] && exit $SMF_EXIT_ERR_CONFIG
    467 	exit $SMF_EXIT_OK
    468 fi
    469 
    470 # Any non-loopback IPv4 interfaces with usable addresses up?
    471 if [ -n "`/sbin/ifconfig -a4u`" ]; then
    472     	/sbin/ifconfig -a4u | while read intf addr rest; do
    473 		[ $intf = inet ] && [ $addr != 127.0.0.1 ] &&
    474 		[ $addr != 0.0.0.0 ] && exit $SMF_EXIT_OK
    475 	done && exit $SMF_EXIT_OK
    476 fi
    477 
    478 # Any DHCP interfaces started?
    479 [ -n "`/sbin/ifconfig -a4 dhcp status 2>/dev/null`" ] && exit $SMF_EXIT_OK
    480 
    481 # Any non-loopback IPv6 interfaces up?
    482 if [ -n "`/sbin/ifconfig -au6`" ]; then
    483 	/sbin/ifconfig -au6 | while read intf addr rest; do
    484 		[ $intf = inet6 ] && [ $addr != ::1/128 ] && exit $SMF_EXIT_OK
    485 	done && exit $SMF_EXIT_OK
    486 fi
    487 
    488 # This service was supposed to configure something yet didn't.  Exit
    489 # with config error.
    490 exit $SMF_EXIT_ERR_CONFIG
    491