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