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. Any /etc/hostname*.intf 309# files take precedence over ipadm defined configurations except when 310# we are in a non-global zone and Layer-3 protection of IP addresses is 311# enforced on the interface by the global zone. 312# 313for showif_output in `/sbin/ipadm show-if -p -o ifname,state,current`; do 314 intf=`echo $showif_output | /usr/bin/cut -f1 -d:` 315 state=`echo $showif_output | /usr/bin/cut -f2 -d:` 316 current=`echo $showif_output | /usr/bin/cut -f3 -d:` 317 if [[ "$state" != "disabled" && $current != *Z* ]]; then 318 # 319 # skip if not a persistent interface, or if it should get IP 320 # configuration from the global zone ('Z' flag is set) 321 # 322 continue; 323 elif is_iptun $intf; then 324 # skip IP tunnel interfaces plumbed by net-iptun 325 continue; 326 elif [ -f /etc/hostname.$intf ] || [ -f /etc/hostname6.$intf ]; then 327 if [[ $current != *Z* ]]; then 328 echo "found /etc/hostname.$intf "\ 329 "or /etc/hostname6.$intf, "\ 330 "ignoring ipadm configuration" > /dev/msglog 331 continue; 332 else 333 echo "Ignoring /etc/hostname*.$intf" > /dev/msglog 334 /sbin/ifconfig $intf unplumb > /dev/null 2>&1 335 /sbin/ifconfig $intf inet6 unplumb > /dev/null 2>&1 336 fi 337 fi 338 339 # Enable the interface managed by ipadm 340 /sbin/ipadm enable-if -t $intf 341done 342 343# 344# Process the /etc/hostname[6].* files for IPMP interfaces. Processing these 345# before non-IPMP interfaces avoids accidental implicit IPMP group creation. 346# 347[ -n "$ipmp_created" ] && if_configure inet "IPMP" $ipmp_created 348[ -n "$ipmp6_created" ] && if_configure inet6 "IPMP" $ipmp6_created 349 350# 351# Process the /etc/hostname[6].* files for non-IPMP interfaces. 352# 353[ -n "$inet_plumbed" ] && if_configure inet "" $inet_plumbed 354[ -n "$inet6_plumbed" ] && if_configure inet6 "" $inet6_plumbed 355 356# 357# For the IPv4 and IPv6 interfaces that failed to plumb, find (or create) 358# IPMP meta-interfaces to host their data addresses. 359# 360[ -n "$inet_failed" ] && move_addresses inet 361[ -n "$inet6_failed" ] && move_addresses inet6 362 363# Run DHCP if requested. Skip boot-configured interface. 364interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`" 365if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then 366 # 367 # First find the primary interface. Default to the first 368 # interface if not specified. First primary interface found 369 # "wins". Use care not to "reconfigure" a net-booted interface 370 # configured using DHCP. Run through the list of interfaces 371 # again, this time trying DHCP. 372 # 373 i4d_fail= 374 firstif= 375 primary= 376 ORIGIFS="$IFS" 377 IFS="${IFS}." 378 set -- $interface_names 379 380 while [ $# -ge 2 ]; do 381 shift 382 [ -z "$firstif" ] && firstif=$1 383 384 for i in `shcat /etc/dhcp\.$1`; do 385 if [ "$i" = primary ]; then 386 primary=$1 387 break 388 fi 389 done 390 391 [ -n "$primary" ] && break 392 shift 393 done 394 395 [ -z "$primary" ] && primary="$firstif" 396 cmdline=`shcat /etc/dhcp\.${primary}` 397 398 if [ "$_INIT_NET_IF" != "$primary" ]; then 399 echo "starting DHCP on primary interface $primary" 400 /sbin/ifconfig $primary auto-dhcp primary $cmdline 401 # Exit code 4 means ifconfig timed out waiting for dhcpagent 402 [ $? != 0 ] && [ $? != 4 ] && i4d_fail="$i4d_fail $primary" 403 fi 404 405 set -- $interface_names 406 407 while [ $# -ge 2 ]; do 408 shift 409 cmdline=`shcat /etc/dhcp\.$1` 410 if [ "$1" != "$primary" -a \ 411 "$1" != "$_INIT_NET_IF" ]; then 412 echo "starting DHCP on interface $1" 413 /sbin/ifconfig $1 dhcp start wait 0 $cmdline 414 # Exit code can't be timeout when wait is 0 415 [ $? != 0 ] && i4d_fail="$i4d_fail $1" 416 fi 417 shift 418 done 419 IFS="$ORIGIFS" 420 unset ORIGIFS 421 [ -n "$i4d_fail" ] && warn_failed_ifs "configure IPv4 DHCP" "$i4d_fail" 422fi 423 424# In order to avoid bringing up the interfaces that have 425# intentionally been left down, perform RARP only if the system 426# has no configured hostname in /etc/nodename 427hostname="`shcat /etc/nodename 2>/dev/null`" 428if [ "$_INIT_NET_STRATEGY" = "rarp" -o -z "$hostname" ]; then 429 /sbin/ifconfig -adD4 auto-revarp netmask + broadcast + up 430fi 431 432# 433# If the /etc/defaultrouter file exists, process it now so that the next 434# stage of booting will have access to NFS. 435# 436if [ -f /etc/defaultrouter ]; then 437 while read router rubbish; do 438 case "$router" in 439 '#'* | '') ;; # Ignore comments, empty lines 440 *) /sbin/route -n add default -gateway $router ;; 441 esac 442 done </etc/defaultrouter 443fi 444 445# 446# If we get here and were not asked to plumb any IPv4 interfaces, look 447# for boot properties that direct us. 448# 449# - The "network-interface" property is required and indicates the 450# interface name. 451# - The "xpv-hcp" property, if present, is used by the hypervisor 452# tools to indicate how the specified interface should be configured. 453# Permitted values are "dhcp" and "off", where "off" indicates static 454# IP configuration. 455# 456# In the case where "xpv-hcp" is set to "dhcp", no further properties 457# are required or examined. 458# 459# In the case where "xpv-hcp" is not present or set to "off", the 460# "host-ip" and "subnet-mask" properties are used to configure 461# the specified interface. The "router-ip" property, if present, 462# is used to add a default route. 463# 464nic="`/sbin/devprop network-interface`" 465if smf_is_globalzone && [ -z "$inet_list" ] && [ -n "$nic" ]; then 466 hcp="`/sbin/devprop xpv-hcp`" 467 case "$hcp" in 468 "dhcp") 469 /sbin/ifconfig $nic plumb 2>/dev/null 470 [ -n "`/sbin/ifconfig $nic 2>/dev/null`" ] && ( 471 # The interface is successfully plumbed, so 472 # modify "inet_list" to force the exit code 473 # checks to work. 474 inet_list=$nic; 475 # Given that this is the only IPv4 interface, 476 # we assert that it is primary. 477 echo "starting DHCP on primary interface $primary"; 478 /sbin/ifconfig $nic auto-dhcp primary; 479 # Exit code 4 means ifconfig timed out waiting 480 # for dhcpagent 481 [ $? != 0 ] && [ $? != 4 ] && \ 482 i4d_fail="$i4d_fail $nic"; 483 ) 484 ;; 485 486 "off"|"") 487 /sbin/devprop host-ip subnet-mask router-ip | ( 488 read ip; 489 read mask; 490 read router; 491 [ -n "$ip" ] && [ -n "$mask" ] && \ 492 /sbin/ifconfig $nic plumb 2>/dev/null 493 [ -n "`/sbin/ifconfig $nic 2>/dev/null`" ] && ( 494 # The interface is successfully 495 # plumbed, so modify "inet_list" to 496 # force the exit code checks to work. 497 inet_list=$nic; 498 /sbin/ifconfig $nic inet $ip \ 499 netmask $mask broadcast + up 2>/dev/null; 500 [ -n "$router" ] && route add \ 501 default $router 2>/dev/null; 502 ) 503 ) 504 ;; 505 esac 506fi 507 508# 509# We tell smf this service is online if any of the following is true: 510# - no interfaces were configured for plumbing and no DHCP failures 511# - any non-loopback IPv4 interfaces are up and have a non-zero address 512# - there are any DHCP interfaces started 513# - any non-loopback IPv6 interfaces are up 514# 515# If we weren't asked to configure any interfaces, exit 516if [ -z "$inet_list" ] && [ -z "$inet6_list" ]; then 517 # Config error if DHCP was attempted without plumbed interfaces 518 [ -n "$i4d_fail" ] && exit $SMF_EXIT_ERR_CONFIG 519 exit $SMF_EXIT_OK 520fi 521 522# Any non-loopback IPv4 interfaces with usable addresses up? 523if [ -n "`/sbin/ifconfig -a4u`" ]; then 524 /sbin/ifconfig -a4u | while read intf addr rest; do 525 [ $intf = inet ] && [ $addr != 127.0.0.1 ] && 526 [ $addr != 0.0.0.0 ] && exit $SMF_EXIT_OK 527 done && exit $SMF_EXIT_OK 528fi 529 530# Any DHCP interfaces started? 531[ -n "`/sbin/ifconfig -a4 dhcp status 2>/dev/null`" ] && exit $SMF_EXIT_OK 532 533# Any non-loopback IPv6 interfaces up? 534if [ -n "`/sbin/ifconfig -au6`" ]; then 535 /sbin/ifconfig -au6 | while read intf addr rest; do 536 [ $intf = inet6 ] && [ $addr != ::1/128 ] && exit $SMF_EXIT_OK 537 done && exit $SMF_EXIT_OK 538fi 539 540# This service was supposed to configure something yet didn't. Exit 541# with config error. 542exit $SMF_EXIT_ERR_CONFIG 543