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 (c) 2010, Oracle and/or its affiliates. All rights reserved. 24# 25# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T. 26# All rights reserved. 27# 28# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T 29# The copyright notice above does not evidence any 30# actual or intended publication of such source code. 31# 32 33. /lib/svc/share/smf_include.sh 34. /lib/svc/share/net_include.sh 35 36# 37# This file replaces the Solaris 10 net-physical script in S10C at 38# boot time. Any S10C specific changes to net-physical script needs 39# to be made in this file. 40# 41 42# 43# In a shared-IP zone we need this service to be up, but all of the work 44# it tries to do is irrelevant (and will actually lead to the service 45# failing if we try to do it), so just bail out. 46# In exclusive-IP zones we proceed. 47# 48if [ `/sbin/zonename -t` = shared ]; then 49 exit 0 50fi 51 52# Print warnings to console 53warn_failed_ifs() { 54 echo "Failed to $1 interface(s): $2" >/dev/msglog 55} 56 57# 58# Cause ifconfig to not automatically start in.mpathd when IPMP groups are 59# configured. This is not strictly necessary but makes it so that in.mpathd 60# will always be started explicitly from /etc/init.d/inetinit, when we're 61# sure that /usr is mounted. 62# 63SUNW_NO_MPATHD=; export SUNW_NO_MPATHD 64 65smf_netstrategy 66 67# 68# If the system was net booted by DHCP, hand DHCP management off to the 69# DHCP agent (ifconfig communicates to the DHCP agent through the 70# loopback interface). 71# 72if [ -n "$_INIT_NET_IF" -a "$_INIT_NET_STRATEGY" = "dhcp" ]; then 73 /sbin/dhcpagent -a 74fi 75 76# 77# For IPv4 interfaces that were configured by the kernel and not 78# configured by DHCP, reset the netmask using the local "/etc/netmasks" 79# file if one exists, and then reset the broadcast address based on 80# the netmask. 81# 82/sbin/ifconfig -auD4 netmask + broadcast + 83 84# 85# All the IPv4 and IPv6 interfaces are plumbed before doing any 86# interface configuration. This prevents errors from plumb failures 87# getting mixed in with the configured interface lists that the script 88# outputs. 89# 90# Moreover in S10C, we process IPMP interfaces before non-IPMP 91# interfaces to avoid accidental implicit IPMP group creation. 92# Therefore we keep track of IPMP and non-IPMP interfaces in two 93# different lists i.e. ipmp[6]_list vs inet[6]_list. 94 95# 96# Get the list of IPv4 interfaces to configure by breaking 97# /etc/hostname.* into separate args by using "." as a shell separator 98# character. 99# 100interface_names="`echo /etc/hostname.*[0-9] 2>/dev/null`" 101if [ "$interface_names" != "/etc/hostname.*[0-9]" ]; then 102 ORIGIFS="$IFS" 103 IFS="$IFS." 104 set -- $interface_names 105 IFS="$ORIGIFS" 106 while [ $# -ge 2 ]; do 107 shift 108 if [ "$1" = "xx0" ]; then 109 # 110 # For some unknown historical reason the xx0 111 # ifname is ignored. 112 # 113 shift 114 continue 115 fi 116 if [ $# -gt 1 -a "$2" != "/etc/hostname" ]; then 117 while [ $# -gt 1 -a "$1" != "/etc/hostname" ]; do 118 shift 119 done 120 else 121 read one rest < /etc/hostname.$1 122 if [ "$one" = ipmp ]; then 123 ipmp_list="$ipmp_list $1" 124 else 125 inet_list="$inet_list $1" 126 fi 127 shift 128 fi 129 done 130fi 131 132# 133# Get the list of IPv6 interfaces to configure by breaking 134# /etc/hostname6.* into separate args by using "." as a shell separator 135# character. 136# 137interface_names="`echo /etc/hostname6.*[0-9] 2>/dev/null`" 138if [ "$interface_names" != "/etc/hostname6.*[0-9]" ]; then 139 ORIGIFS="$IFS" 140 IFS="$IFS." 141 set -- $interface_names 142 IFS="$ORIGIFS" 143 while [ $# -ge 2 ]; do 144 shift 145 if [ $# -gt 1 -a "$2" != "/etc/hostname6" ]; then 146 while [ $# -gt 1 -a "$1" != "/etc/hostname6" ]; do 147 shift 148 done 149 else 150 read one rest < /etc/hostname6.$1 151 if [ "$one" = ipmp ]; then 152 ipmp6_list="$ipmp6_list $1" 153 else 154 inet6_list="$inet6_list $1" 155 fi 156 shift 157 fi 158 done 159fi 160 161# 162# Create all of the IPv4 IPMP interfaces. 163# 164if [ -n "$ipmp_list" ]; then 165 set -- $ipmp_list 166 while [ $# -gt 0 ]; do 167 if /sbin/ifconfig $1 ipmp; then 168 ipmp_created="$ipmp_created $1" 169 else 170 ipmp_failed="$ipmp_failed $1" 171 fi 172 shift 173 done 174 [ -n "$ipmp_failed" ] && warn_failed_ifs "create IPv4 IPMP" \ 175 "$ipmp_failed" 176fi 177 178# 179# Step through the IPv4 interface list and try to plumb every interface. 180# Generate list of plumbed and failed IPv4 interfaces. 181# 182if [ -n "$inet_list" ]; then 183 set -- $inet_list 184 while [ $# -gt 0 ]; do 185 /sbin/ifconfig $1 plumb 186 if /sbin/ifconfig $1 inet >/dev/null 2>&1; then 187 inet_plumbed="$inet_plumbed $1" 188 else 189 inet_failed="$inet_failed $1" 190 fi 191 shift 192 done 193 [ -n "$inet_failed" ] && warn_failed_ifs "plumb IPv4" $inet_failed 194fi 195 196# 197# Step through the IPv6 interface list and plumb every interface. 198# Generate list of plumbed and failed IPv6 interfaces. Each plumbed 199# interface will be brought up later, after processing any contents of 200# the /etc/hostname6.* file. 201# 202if [ -n "$inet6_list" ]; then 203 set -- $inet6_list 204 while [ $# -gt 0 ]; do 205 /sbin/ifconfig $1 inet6 plumb 206 if /sbin/ifconfig $1 inet6 >/dev/null 2>&1; then 207 inet6_plumbed="$inet6_plumbed $1" 208 else 209 inet6_failed="$inet6_failed $1" 210 fi 211 shift 212 done 213 [ -n "$inet6_failed" ] && warn_failed_ifs "plumb IPv6" $inet6_failed 214fi 215 216# 217# Create all of the IPv6 IPMP interfaces. 218# 219if [ -n "$ipmp6_list" ]; then 220 set -- $ipmp6_list 221 while [ $# -gt 0 ]; do 222 if /sbin/ifconfig $1 inet6 ipmp; then 223 ipmp6_created="$ipmp6_created $1" 224 else 225 ipmp6_failed="$ipmp6_failed $1" 226 fi 227 shift 228 done 229 [ -n "$ipmp6_failed" ] && warn_failed_ifs "create IPv6 IPMP" \ 230 "$ipmp6_failed" 231fi 232 233# 234# Process IPMP interfaces before non-IPMP interfaces 235# to avoid accidental implicit IPMP group creation. 236# 237if [ -n "$ipmp_created" ]; then 238 i4s_fail= 239 echo "configuring IPv4 IPMP interfaces:\c" 240 set -- $ipmp_created 241 while [ $# -gt 0 ]; do 242 inet_process_hostname /sbin/ifconfig $1 inet \ 243 </etc/hostname.$1 >/dev/null 244 [ $? != 0 ] && i4s_fail="$i4s_fail $1" 245 echo " $1\c" 246 shift 247 done 248 echo "." 249 [ -n "$i4s_fail" ] && warn_failed_ifs "configure IPv4 IPMP" \ 250 $i4s_fail 251fi 252 253if [ -n "$ipmp6_created" ]; then 254 i6_fail= 255 echo "configuring IPv6 IPMP interfaces:\c" 256 set -- $ipmp6_created 257 while [ $# -gt 0 ]; do 258 inet6_process_hostname /sbin/ifconfig $1 inet6 \ 259 </etc/hostname6.$1 >/dev/null && 260 /sbin/ifconfig $1 inet6 up 261 [ $? != 0 ] && i6_fail="$i6_fail $1" 262 echo " $1\c" 263 shift 264 done 265 echo "." 266 [ -n "$i6_fail" ] && warn_failed_ifs "configure IPv6 IPMP" \ 267 $i6_fail 268fi 269 270# 271# Process the /etc/hostname.* files of plumbed IPv4 interfaces. If an 272# /etc/hostname file is not present or is empty, the ifconfig auto-dhcp 273# / auto-revarp command will attempt to set the address, later. 274# 275# If /etc/hostname.lo0 exists the loop below will do additional 276# configuration of lo0. 277# 278if [ -n "$inet_plumbed" ]; then 279 i4s_fail= 280 echo "configuring IPv4 interfaces:\c" 281 set -- $inet_plumbed 282 while [ $# -gt 0 ]; do 283 l3protect=`/sbin/ifconfig $1|grep -c L3PROTECT` 284 if [ $l3protect != 0 ]; then 285 echo "Ignoring /etc/hostname.$1" > /dev/msglog 286 else 287 inet_process_hostname /sbin/ifconfig $1 inet \ 288 </etc/hostname.$1 >/dev/null 289 [ $? != 0 ] && i4s_fail="$i4s_fail $1" 290 echo " $1\c" 291 fi 292 shift 293 done 294 echo "." 295 [ -n "$i4s_fail" ] && warn_failed_ifs "configure IPv4" $i4s_fail 296fi 297 298# 299# Process the /etc/hostname6.* files of plumbed IPv6 interfaces. After 300# processing the hostname6 file, bring the interface up. If 301# /etc/hostname6.lo0 exists the loop below will do additional 302# configuration of lo0. 303# 304if [ -n "$inet6_plumbed" ]; then 305 i6_fail= 306 echo "configuring IPv6 interfaces:\c" 307 set -- $inet6_plumbed 308 while [ $# -gt 0 ]; do 309 l3protect=`/sbin/ifconfig $1|grep -c L3PROTECT` 310 if [ $l3protect != 0 ]; then 311 echo "Ignoring /etc/hostname6.$1" > /dev/msglog 312 else 313 inet6_process_hostname /sbin/ifconfig $1 inet6 \ 314 </etc/hostname6.$1 >/dev/null && 315 /sbin/ifconfig $1 inet6 up 316 [ $? != 0 ] && i6_fail="$i6_fail $1" 317 echo " $1\c" 318 fi 319 shift 320 done 321 echo "." 322 [ -n "$i6_fail" ] && warn_failed_ifs "configure IPv6" $i6_fail 323fi 324 325# Run DHCP if requested. Skip boot-configured interface. 326interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`" 327if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then 328 # 329 # First find the primary interface. Default to the first 330 # interface if not specified. First primary interface found 331 # "wins". Use care not to "reconfigure" a net-booted interface 332 # configured using DHCP. Run through the list of interfaces 333 # again, this time trying DHCP. 334 # 335 i4d_fail= 336 firstif= 337 primary= 338 ORIGIFS="$IFS" 339 IFS="${IFS}." 340 set -- $interface_names 341 342 while [ $# -ge 2 ]; do 343 shift 344 [ -z "$firstif" ] && firstif=$1 345 346 for i in `shcat /etc/dhcp\.$1`; do 347 if [ "$i" = primary ]; then 348 primary=$1 349 break 350 fi 351 done 352 353 [ -n "$primary" ] && break 354 shift 355 done 356 357 [ -z "$primary" ] && primary="$firstif" 358 cmdline=`shcat /etc/dhcp\.${primary}` 359 360 if [ "$_INIT_NET_IF" != "$primary" ]; then 361 echo "starting DHCP on primary interface $primary" 362 /sbin/ifconfig $primary auto-dhcp primary $cmdline 363 # Exit code 4 means ifconfig timed out waiting for dhcpagent 364 [ $? != 0 ] && [ $? != 4 ] && i4d_fail="$i4d_fail $primary" 365 fi 366 367 set -- $interface_names 368 369 while [ $# -ge 2 ]; do 370 shift 371 cmdline=`shcat /etc/dhcp\.$1` 372 if [ "$1" != "$primary" -a \ 373 "$1" != "$_INIT_NET_IF" ]; then 374 echo "starting DHCP on interface $1" 375 /sbin/ifconfig $1 dhcp start wait 0 $cmdline 376 # Exit code can't be timeout when wait is 0 377 [ $? != 0 ] && i4d_fail="$i4d_fail $1" 378 fi 379 shift 380 done 381 IFS="$ORIGIFS" 382 unset ORIGIFS 383 [ -n "$i4d_fail" ] && warn_failed_ifs "configure IPv4 DHCP" $i4d_fail 384fi 385 386# In order to avoid bringing up the interfaces that have 387# intentionally been left down, perform RARP only if the system 388# has no configured hostname in /etc/nodename 389hostname="`shcat /etc/nodename 2>/dev/null`" 390if [ "$_INIT_NET_STRATEGY" = "rarp" -o -z "$hostname" ]; then 391 /sbin/ifconfig -adD4 auto-revarp netmask + broadcast + up 392fi 393 394# 395# Process IPv4 and IPv6 interfaces that failed to plumb. Find an 396# alternative interface to host the addresses. 397# 398[ -n "$inet_failed" ] && move_addresses inet 399 400[ -n "$inet6_failed" ] && move_addresses inet6 401 402# 403# If the /etc/defaultrouter file exists, process it now so that the next 404# stage of booting will have access to NFS. 405# 406if [ -f /etc/defaultrouter ]; then 407 while read router rubbish; do 408 case "$router" in 409 '#'* | '') ;; # Ignore comments, empty lines 410 *) /sbin/route -n add default -gateway $router ;; 411 esac 412 done </etc/defaultrouter 413fi 414 415# 416# We tell smf this service is online if any of the following is true: 417# - no interfaces were configured for plumbing and no DHCP failures 418# - there are any DHCP interfaces started 419# - any non-loopback, non-DHCP IPv4 interfaces are up and have a non-zero 420# address 421# - any non-loopback IPv6 interfaces are up 422# 423# If we weren't asked to configure any interfaces, exit 424if [ -z "$inet_list" ] && [ -z "$inet6_list" ]; then 425 # Config error if DHCP was attempted without plumbed interfaces 426 [ -n "$i4d_fail" ] && exit $SMF_EXIT_ERR_CONFIG 427 exit $SMF_EXIT_OK 428fi 429 430# Any DHCP interfaces? 431[ -n "`/sbin/ifconfig -a4 dhcp status 2>/dev/null`" ] && exit $SMF_EXIT_OK 432 433# Any non-loopback, non-DHCP IPv4 interfaces with usable addresses up? 434if [ -n "`/sbin/ifconfig -a4uD`" ]; then 435 /sbin/ifconfig -a4uD | while read intf addr rest; do 436 [ $intf = inet ] && [ $addr != 127.0.0.1 ] && 437 [ $addr != 0.0.0.0 ] && exit 0 438 done && exit $SMF_EXIT_OK 439fi 440 441# Any non-loopback IPv6 interfaces up? 442if [ -n "`/sbin/ifconfig -au6`" ]; then 443 /sbin/ifconfig -au6 | while read intf addr rest; do 444 [ $intf = inet6 ] && [ $addr != ::1/128 ] && exit 0 445 done && exit $SMF_EXIT_OK 446fi 447 448# This service was supposed to configure something yet didn't. Exit 449# with config error. 450exit $SMF_EXIT_ERR_CONFIG 451