#!/usr/sbin/sh # # Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. # # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T. # All rights reserved. # . /lib/svc/share/smf_include.sh . /lib/svc/share/net_include.sh # # Version history: # # There are two version properties in svc:/network/physical:default. # upgrade/version is defined as 1 in the manifest and when /etc/hostname.* is # obsoleted, it is changed to 2. upgrade/nwamd_version is migrated from # nwamd/version of the nwam instance and is the one currently used to track # version. # # v0: NWAM Phase 0/0.5 # - no version property # v1: NWAM Phase 1 # - nwamd/version = 1 in nwam instance # v2: Hostname obsoleted # - upgrade/version = 2 in default instance # v2: Instances merge (nwam instance obsoleted) # - upgrade/nwamd_version = 2 in default instance # - nwaminst/upgraded = true in nwam instance # v3: Highlander (merged repo, nwam instance removed) # - upgrade/nwamd_version = 3 # # Make sure that the libraries essential to this stage of booting can be found. LD_LIBRARY_PATH=/lib; export LD_LIBRARY_PATH ID_NODE_FMRI="svc:/system/identity:node" NET_INSTALL_FMRI="svc:/network/install:default" NET_LOC_FMRI="svc:/network/location:default" # # Convert a device-based nic name to a physical link name. # nic2phys () { /usr/sbin/dladm show-phys -p -odevice,link | while IFS=':' read device phys; do if [[ $device == $1 ]]; then print $phys return fi done print $1 } # # Use boot properties, if present, to configure an interface. # # - The "network-interface" property is required and indicates the # interface name. # - The "xpv-hcp" property, if present, is used by the hypervisor # tools to indicate how the specified interface should be configured. # Permitted values are "dhcp" and "off", where "off" indicates static # IP configuration. # # In the case where "xpv-hcp" is set to "dhcp", no further properties # are required or examined. # # In the case where "xpv-hcp" is not present or set to "off", the # "host-ip" and "subnet-mask" properties are used to configure # the specified interface. The "router-ip" property, if present, # is used to add a default route. # config_bootprop () { nic="`/usr/sbin/devprop network-interface 2>/dev/null`" [ -z "$nic" ] && return; phys=`nic2phys $nic` echo "Configuring network for guest domain." hcp="`/usr/sbin/devprop xpv-hcp`" case "$hcp" in "dhcp") $IFCONFIG $phys plumb 2>/dev/null [ -n "`$IFCONFIG $phys 2>/dev/null`" ] && ( # The interface is successfully plumbed, so # modify "cfg_if_list" to force the exit code # checks to work. cfg_if_list=$phys; # Given that this is the only IPv4 interface, # we assert that it is primary. echo "starting DHCP on primary interface $primary"; $IFCONFIG $phys auto-dhcp primary; # Exit code 4 means ifconfig timed out waiting # for dhcpagent [ $? != 0 -a $? != 4 ] && \ i4d_fail="$i4d_fail $phys"; ) ;; "off"|"") /usr/sbin/devprop host-ip subnet-mask router-ip || ( read ip; read mask; read router; [ -n "$ip" ] && [ -n "$mask" ] && \ $IFCONFIG $phys plumb 2>/dev/null [ -n "`$IFCONFIG $phys 2>/dev/null`" ] && ( # The interface is successfully # plumbed, so modify "cfg_if_list" to # force the exit code checks to work. cfg_if_list=$phys; $IFCONFIG $phys inet $ip \ netmask $mask broadcast + up 2>/dev/null; [ -n "$router" ] && route add \ default $router 2>/dev/null; ) ) ;; esac } # # Network configuration for network installs is obtained manually (via the # PROM or CLI during boot) or via DHCP. In the case of DHCP, the IPv4 # interface should be adopted. In the case of a manual configuration, the # configuration should be retrieved using netbootinfo and the interface and, # optionally, a default route should be configured using the proper CLIs. # # Note that iSCSI is a special case since it needs to configure its interface # itself in the kernel. # config_netinstall () { NETBOOTINFO=/usr/lib/inet/wanboot/netbootinfo # # netbootinfo returns an error in the non-network boot case. So, # just return. # strategy=`$NETBOOTINFO net-config-strategy 2>/dev/null` if [ $? -ne 0 -o -z "$strategy" -o "$strategy" = "none" ]; then return fi echo "Configuring network using boot properties." nic=`$NETBOOTINFO interface-name 2>/dev/null` phys=`nic2phys $nic` if [ $? -ne 0 -o -z "$phys" -o "$phys" = "none" ]; then echo "Failed to obtain network interface used to" \ "boot from the network.\nConfiguration bypassed." return fi # # It is possible that the kernel has already plumbed and # configured the interface (e.g., iSCSI boot). If so, # just return. # state=`$IPADM show-if -p -o state $phys 2>/dev/null` if [ $? -eq 0 -a "$state" = "ok" ] ; then echo "$phys has already been configured. No" \ "need to reconfigure.\nConfiguration bypassed." return fi case "$strategy" in "dhcp") # # Instruct dhcpagent to take over control of the interface. # /usr/sbin/dhcpagent -a cfg_if_list=$phys echo "Adopted DHCP configured interface, $phys." ;; "manual") ip=`$NETBOOTINFO host-ip 2>/dev/null` if [ $? -ne 0 -o -z "$ip" -o "$ip" = "none" ]; then echo "Failed to obtain IP address for manual" \ "configuration.\nConfiguration bypassed." return fi mask=`$NETBOOTINFO subnet-mask 2>/dev/null` if [ $? -ne 0 -o -z "$mask" -o "$mask" = "none" ]; then echo "Failed to obtain netmask for manual" \ "configuration.\nConfiguration bypassed." return fi # # ipadm requires CIDR prefixlen so convert # mask to plen. # plen=`netmask2plen $mask` if [ $? -ne 0 -o -z "$plen" ]; then echo "Failed to configure network using" \ "boot parameters." echo "Could not convert $mask to CIDR prefixlen." return fi # # Configure the interface. No need for it to be # persistent. # cfg_if_list=$phys $IPADM show-if $phys >/dev/null 2>&1 if [ $? -ne 0 ]; then $IPADM create-ip -t $phys if [ $? -ne 0 ]; then warn_failed_ifs "create IPv4" "$phys" return fi fi $IPADM create-addr -t -T static -a \ local=$ip/$plen $phys/netboot >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Failed to configure address $ip/$plen on $phys" warn_failed_ifs "plumb IPv4" "$phys" return fi echo "Configured $phys using boot parameters." router=`$NETBOOTINFO router-ip 2>/dev/null` if [ $? -ne 0 -o -z "$router" -o "$router" = "none" ]; then return fi /usr/sbin/route add default $router -ifp $phys >/dev/null 2>&1 /usr/sbin/route get default $router -ifp $phys >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Failed to configure default route using" \ "boot parameter:\nrouter-ip=$router" return fi echo "Added default route using boot parameters." ;; esac } # # add_defaultrouter_comment 1|0 # # Add a comment to the beginning of /etc/defaultrouter, indicating that the # router specified here will be used globally, for all NCPs, and that the # route -p option should be used to create per-NCP static routes. # # If the first argument is '1', the second argument must should specify the # NCP to which router(s) present in /etc/defaultrouter were added. If it is # '0', no routers existed in the file. # add_defaultrouter_comment() { typeset route_added=$1 typeset ncp=$2 typeset tmpfile=/etc/defaultrouter.tmp echo "#" >${tmpfile} echo "# This file is deprecated. Default routes will be created" \ "for any router" >>${tmpfile} echo "# addresses specified here, but they will not change when the" \ "underlying" >>${tmpfile} echo "# network configuration profile (NCP) changes. For" \ "NCP-specific static" >>${tmpfile} echo "# routes, the '-p' option of the route(1M) command should be" \ "used." >>${tmpfile} echo "#" >>${tmpfile} echo "# See netcfg(1M) for information about network configuration" \ "profiles." >>${tmpfile} echo "#" >>${tmpfile} if [ $route_added -eq 1 ]; then echo "# Any router addresses present in this file at upgrade" \ "were applied to the" >>${tmpfile} echo "# active NCP at that time ($ncp)." >>${tmpfile} echo "#" >>${tmpfile} fi $CP ${tmpfile} /etc/defaultrouter $RM -f ${tmpfile} } # # upgrade_defaultrouter # # Add any default routes specified in the /etc/defaultrouter file to # the ncp-specific /etc/inet/static_routes-$ncp file, and prepend # comments to /etc/defaultrouter about global vs. per-ncp static routes. # upgrade_defaultrouter() { typeset ncp=$1 typeset DEFRTR=/etc/defaultrouter typeset STATICRTS=/etc/inet/static_routes found=0 if [ -f $DEFRTR ]; then $GREP -v "^#" $DEFRTR | while read line; do echo default $line >> $STATICRTS found=1 done fi add_defaultrouter_comment $found $ncp if [ -f $STATICRTS ]; then mv $STATICRTS $STATICRTS-$ncp fi } # # Remove the IP configuration in the DefaultFixed profile. Also, disconnect # wireless connections and remove secure objects. # net_unconfigure () { # # In a P2V zone from pre-Highlander (S11FCS), there is no explicit # DefaultFixed NCP. In that case, simply continue and unconfigure any # existing configuration. The other time DefaultFixed NCP doesn't # exist is if unconfigure is done on the first boot after install # where we haven't created the NCP yet. In this situation, continue # on and the remainder of the operations are no-op. # $NETCFG list ncp DefaultFixed >/dev/null 2>/dev/null && \ $NETADM enable -p ncp DefaultFixed # flush the forwarding table, including persistent entries /usr/sbin/route -p flush $RM -f /etc/defaultrouter # # It is not possible to release the DHCP leases with "ipadm # delete-addr -r" because when this function is called, the interfaces # are disabled. This means that because active addresses are not # found, the '-r' is ignored. Thus, explicitly remove the lease files # and the DUID and IAID files from /var/dhcp (and also the old # /etc/dhcp) directory. # $RM -f /var/dhcp/*.dhc /var/dhcp/*.dh6 /var/dhcp/duid /var/dhcp/iaid $RM -f /etc/dhcp/*.dhc /etc/dhcp/*.dh6 /etc/dhcp/duid /etc/dhcp/iaid # delete all non-loopback IP interfaces. for intf in $($IPADM show-if -p -o ifname,class); do echo $intf | IFS=':' read ifname ifclass case $ifclass in 'ip' ) $IPADM delete-ip $ifname ;; 'ipmp' ) $IPADM delete-ipmp --force $ifname ;; 'vni' ) $IPADM delete-vni $ifname ;; esac if [ $? -ne 0 ]; then return 1 fi done if smf_is_globalzone; then # disconnect from any connected WiFi links for wifi in $($DLADM show-wifi -p -o link,status); do echo $wifi | IFS=':' read linkname wifistatus if [ "$wifistatus" == "connected" ]; then $DLADM disconnect-wifi $linkname if [ $? -ne 0 ]; then return 1 fi fi done # delete security objects for secobj in $($DLADM show-secobj -p -o object); do $DLADM delete-secobj $secobj || return 1 done fi return 0 } # # Script entry point # # Arguments to net-physical are # method ( start | refresh | stop | upgrade | unconfigure ) # if [ ! -d $VOL_NETCFG_PATH ]; then /usr/bin/mkdir -m 0755 $VOL_NETCFG_PATH /usr/bin/chown netadm:netadm $VOL_NETCFG_PATH fi case "$1" in 'start') # # This service doesn't do anything in a shared-stack zone; but it # needs to be online to meet dependencies. We use this return # value to notify the smf infrastructure that there are no running # processes associated with this online, non-transient service. # smf_configure_ip if [ $? -eq 1 ]; then smf_method_exit $SMF_EXIT_TEMP_TRANSIENT shared_stack \ "$SMF_FMRI does nothing in a shared-stack zone" fi smf_netstrategy # remainder of script is start action ;; 'unconfigure') # Unconfigure the DefaultFixed profile first net_unconfigure || exit $SMF_EXIT_ERR_CONFIG # # Revert property customizations. We revert back to the profile that # was set by the install manifest. # $SVCCFG -s $SMF_FMRI delcust general/enabled || \ exit $SMF_EXIT_ERR_CONFIG $SVCCFG -s $SMF_FMRI delcust netcfg/active_ncp || \ exit $SMF_EXIT_ERR_CONFIG $SVCCFG -s $SMF_FMRI delcust nwamd || exit $SMF_EXIT_ERR_CONFIG $SVCADM refresh $SMF_FMRI # # Destroy user-created NCPs, Locations, ENMs and Known WLANs. If the # active_ncp is set to a user-created NCP in the install manifest, it # will not be removed; but that is exactly what we want by reverting # to the installed settings. # $NETCFG destroy -a 2>/dev/null || exit $SMF_EXIT_ERR_CONFIG # # Remove the nonpersistent property group from svc:/network/location, # so that it's clear we're making a clean start when coming up after # an unconfig. # $SVCPROP -cq -p location $NET_LOC_FMRI 2>/dev/null if [ $? -eq 0 ]; then $SVCCFG -s $NET_LOC_FMRI delpg location 2>/dev/null [ $? -gt 0 ] && exit $SMF_EXIT_ERR_CONFIG $SVCADM refresh $NET_LOC_FMRI fi $SVCCFG -s $NET_INSTALL_FMRI delcust || exit $SMF_EXIT_ERR_CONFIG $SVCADM refresh $NET_INSTALL_FMRI exit $SMF_EXIT_OK ;; 'refresh') /usr/bin/pkill -HUP -z `smf_zonename` nwamd exit $SMF_EXIT_OK ;; 'stop') # Nothing to do in a shared stack zone. smf_configure_ip [ $? -eq 1 ] && exit $SMF_EXIT_OK /usr/bin/pkill -z `smf_zonename` nwamd # Kill any processes left in service contract. For example, # the dhcpagent in the DHCP netinstall case. smf_kill_contract $2 TERM 1 [ $? -ne 0 ] && exit $SMF_EXIT_ERR_CONFIG exit $SMF_EXIT_OK ;; 'upgrade') /lib/inet/nwamd -u case $? in '-1') exit $SMF_EXIT_ERR_FATAL;; '1') # # return value of 1 indicates upgrade was required # and completed successfully; in this case, we also # need to upgrade the static routing config # upgrade_defaultrouter `get_active_ncp` ;; esac exit $SMF_EXIT_OK ;; *) echo "Usage: $0 { start | stop | refresh | unconfigure | upgrade }" exit 1 ;; esac if smf_is_globalzone; then # Initialize device properties $DLADM init-devprop # Bring up EoIB datalinks $DLADM up-eoib # Update PVID on interfaces configured with VLAN 1 update_pvid # # Bring up simnets, link aggregations and initialize security objects. # Note that link property initialization is deferred until after IP # interfaces are plumbed to ensure that the links will not be unloaded # (and the property settings lost). We should bring up simnets prior # to VLANs/Aggrs to enable creation of VLANs/Aggrs over simnets. # $DLADM up-simnet $DLADM up-aggr $DLADM up-vlan $DLADM up-part $DLADM init-secobj $DLADM up-vxlan # # Bring up VNICs # $DLADM up-vnic # # Bring up capture interfaces # $DLADM up-cap # # Create flows via flowadm here, as upgrade file handling contains # flowadm commands which may require flows to be initiated. # /usr/sbin/flowadm init-flow # # Upgrade handling. The upgrade file consists of a series of dladm(1M) # commands. # upgrade_script=/var/svc/profile/upgrade_datalink if [ -f "${upgrade_script}" ]; then . "${upgrade_script}" # # Rename the upgrade script file so that on subsequent reboots # we do not end up applying the same configuration. # /usr/bin/mv "${upgrade_script}" \ "${upgrade_script}".app.`/usr/bin/date +\%Y\%m\%d\%H\%M\%S` fi # # If the global zone is running as a kernel zone guest, then # IP interface configuration can come from the host through # zonecfg's allowed-address and defrouter properties. # if smf_is_kernelzone; then # # See below. # $IPADM create-ip -z fi else # # In non-global zones, IP interface configuration for normal anets # and EVS anets can come from the global zone via zonecfg's # allowed-address and configure-allowed-address properties. Before we # enable addresses configured in this manner, we need to create # persistent IP interface configuration if it doesn't already # exist. # $IPADM create-ip -z # # Create flows via flowadm # /usr/sbin/flowadm init-flow fi # # Make sure that network/location is enabled (on an upgraded system it will # not be, as it was delivered disabled, and only enabled temporarily when # network/physical:nwam was enabled). # $SVCADM enable $NET_LOC_FMRI # # In order to avoid bringing up the interfaces that have intentionally been # left down, perform RARP only if the system has no configured hostname in the # svc:/system/identity:node SMF service or /etc/nodename # hostname=$($SVCPROP -p config/nodename $ID_NODE_FMRI) [[ "$hostname" = '""' ]] && hostname="" if [[ -z "$hostname" && -e /etc/nodename ]]; then hostname="`shcat /etc/nodename 2>/dev/null`" fi if [ "$_INIT_NET_STRATEGY" = "rarp" -o -z "$hostname" ]; then $IFCONFIG -aLdD4 auto-revarp netmask + broadcast + up fi # # Check for boot properties or netboot info to direct us. config_bootprop # will set cfg_if_list if it configures anything; in this case, we can skip # the config_netinstall check. # if smf_is_globalzone; then config_bootprop fi if [ -z "$cfg_if_list" ] && smf_is_globalzone; then config_netinstall fi # # Start nwamd in foreground; it will daemonize itself # /lib/inet/nwamd || exit $SMF_EXIT_ERR_FATAL # # Identify the appropriate static_routes file, based on the currently # active NCP. # NCP=`get_active_ncp` STATIC_ROUTES="/etc/inet/static_routes-$NCP" SYSVOL_STATIC_ROUTES="${SMF_SYSVOL_FS}/${STATIC_ROUTES}" # # See if static routes were created by install. If so, they were created # under $SMF_SYSVOL_FS. Copy them into their proper place. # if [ -f $SYSVOL_STATIC_ROUTES ]; then echo "Installing persistent routes" if [ -f $STATIC_ROUTES ]; then $CAT $SYSVOL_STATIC_ROUTES | $GREP -v '^#' \ >> $STATIC_ROUTES else $CP $SYSVOL_STATIC_ROUTES $STATIC_ROUTES fi $RM -f $SYSVOL_STATIC_ROUTES fi # # Apply static routes specified in the current NCP's static_routes file, so # that the next stage of booting will have access to NFS. This is done here # as well as in network/routing-setup for that reason. # if [ -f $STATIC_ROUTES ]; then walk_static_routes add $STATIC_ROUTES fi exit $SMF_EXIT_OK