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