xref: /onnv-gate/usr/src/cmd/svc/shell/net_include.sh (revision 12926:599476a18982)
10Sstevel@tonic-gate#!/bin/sh
20Sstevel@tonic-gate#
30Sstevel@tonic-gate# CDDL HEADER START
40Sstevel@tonic-gate#
50Sstevel@tonic-gate# The contents of this file are subject to the terms of the
64121Samaguire# Common Development and Distribution License (the "License").
74121Samaguire# You may not use this file except in compliance with the License.
80Sstevel@tonic-gate#
90Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate# See the License for the specific language governing permissions
120Sstevel@tonic-gate# and limitations under the License.
130Sstevel@tonic-gate#
140Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate#
200Sstevel@tonic-gate# CDDL HEADER END
210Sstevel@tonic-gate#
220Sstevel@tonic-gate#
2312748SSowmini.Varadhan@oracle.COM# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate#
250Sstevel@tonic-gate# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
260Sstevel@tonic-gate# All rights reserved.
270Sstevel@tonic-gate#
280Sstevel@tonic-gate
29*12926SMark.Haywood@Oracle.COMNET_INADDR_ANY="0.0.0.0"
30*12926SMark.Haywood@Oracle.COMNET_IN6ADDR_ANY_INIT="::0"
31*12926SMark.Haywood@Oracle.COM
328485SPeter.Memishian@Sun.COM# Print warnings to console
338485SPeter.Memishian@Sun.COMwarn_failed_ifs() {
348485SPeter.Memishian@Sun.COM	echo "Failed to $1 interface(s):$2" >/dev/msglog
358485SPeter.Memishian@Sun.COM}
368485SPeter.Memishian@Sun.COM
370Sstevel@tonic-gate#
380Sstevel@tonic-gate# shcat file
390Sstevel@tonic-gate#   Simulates cat in sh so it doesn't need to be on the root filesystem.
400Sstevel@tonic-gate#
410Sstevel@tonic-gateshcat() {
420Sstevel@tonic-gate        while [ $# -ge 1 ]; do
430Sstevel@tonic-gate                while read i; do
440Sstevel@tonic-gate                        echo "$i"
450Sstevel@tonic-gate                done < $1
460Sstevel@tonic-gate                shift
470Sstevel@tonic-gate        done
480Sstevel@tonic-gate}
490Sstevel@tonic-gate
50*12926SMark.Haywood@Oracle.COMnet_record_err()
51*12926SMark.Haywood@Oracle.COM{
52*12926SMark.Haywood@Oracle.COM	message=$1
53*12926SMark.Haywood@Oracle.COM	err=$2
54*12926SMark.Haywood@Oracle.COM
55*12926SMark.Haywood@Oracle.COM	echo "$message" | smf_console
56*12926SMark.Haywood@Oracle.COM	if [ $err -ne 0 ]; then
57*12926SMark.Haywood@Oracle.COM		echo "Error code = $err" | smf_console
58*12926SMark.Haywood@Oracle.COM	fi
59*12926SMark.Haywood@Oracle.COM}
60*12926SMark.Haywood@Oracle.COM
610Sstevel@tonic-gate#
628485SPeter.Memishian@Sun.COM# inet_list	list of IPv4 interfaces.
638485SPeter.Memishian@Sun.COM# inet6_list	list of IPv6 interfaces.
648485SPeter.Memishian@Sun.COM# ipmp_list	list of IPMP IPv4 interfaces.
658485SPeter.Memishian@Sun.COM# ipmp6_list	list of IPMP IPv6 interfaces.
668485SPeter.Memishian@Sun.COM# inet_plumbed	list of plumbed IPv4 interfaces.
678485SPeter.Memishian@Sun.COM# inet6_plumbed list of plumbed IPv6 interfaces.
688485SPeter.Memishian@Sun.COM# ipmp_created 	list of created IPMP IPv4 interfaces.
698485SPeter.Memishian@Sun.COM# ipmp6_created	list of created IPMP IPv6 interfaces.
708485SPeter.Memishian@Sun.COM# inet_failed	list of IPv4 interfaces that failed to plumb.
718485SPeter.Memishian@Sun.COM# inet6_failed	list of IPv6 interfaces that failed to plumb.
728485SPeter.Memishian@Sun.COM# ipmp_failed 	list of IPMP IPv4 interfaces that failed to be created.
738485SPeter.Memishian@Sun.COM# ipmp6_failed	list of IPMP IPv6 interfaces that failed to be created.
740Sstevel@tonic-gate#
750Sstevel@tonic-gateunset inet_list inet_plumbed inet_failed \
768485SPeter.Memishian@Sun.COM	inet6_list inet6_plumbed inet6_failed \
778485SPeter.Memishian@Sun.COM	ipmp_list ipmp_created ipmp_failed \
788485SPeter.Memishian@Sun.COM	ipmp6_list ipmp6_created ipmp6_failed
798485SPeter.Memishian@Sun.COM
800Sstevel@tonic-gate#
810Sstevel@tonic-gate# get_physical interface
820Sstevel@tonic-gate#
838485SPeter.Memishian@Sun.COM# Return physical interface corresponding to the given interface.
840Sstevel@tonic-gate#
850Sstevel@tonic-gateget_physical()
860Sstevel@tonic-gate{
870Sstevel@tonic-gate	ORIGIFS="$IFS"
880Sstevel@tonic-gate	IFS="${IFS}:"
890Sstevel@tonic-gate	set -- $1
900Sstevel@tonic-gate	IFS="$ORIGIFS"
910Sstevel@tonic-gate
920Sstevel@tonic-gate	echo $1
930Sstevel@tonic-gate}
940Sstevel@tonic-gate
950Sstevel@tonic-gate#
960Sstevel@tonic-gate# get_logical interface
970Sstevel@tonic-gate#
980Sstevel@tonic-gate# Return logical interface number.  Zero will be returned
998485SPeter.Memishian@Sun.COM# if there is no explicit logical number.
1000Sstevel@tonic-gate#
1010Sstevel@tonic-gateget_logical()
1020Sstevel@tonic-gate{
1030Sstevel@tonic-gate	ORIGIFS="$IFS"
1040Sstevel@tonic-gate	IFS="${IFS}:"
1050Sstevel@tonic-gate	set -- $1
1060Sstevel@tonic-gate	IFS="$ORIGIFS"
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate	if [ -z "$2" ]; then
1090Sstevel@tonic-gate		echo 0
1100Sstevel@tonic-gate	else
1110Sstevel@tonic-gate		echo $2
1120Sstevel@tonic-gate	fi
1130Sstevel@tonic-gate}
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate#
1160Sstevel@tonic-gate# if_comp if1 if2
1170Sstevel@tonic-gate#
1188485SPeter.Memishian@Sun.COM# Compare interfaces.  Do the physical interface names and logical interface
1190Sstevel@tonic-gate# numbers match?
1200Sstevel@tonic-gate#
1210Sstevel@tonic-gateif_comp()
1220Sstevel@tonic-gate{
1238485SPeter.Memishian@Sun.COM	physical_comp $1 $2 && [ `get_logical $1` -eq `get_logical $2` ]
1240Sstevel@tonic-gate}
1258485SPeter.Memishian@Sun.COM
1260Sstevel@tonic-gate#
1270Sstevel@tonic-gate# physical_comp if1 if2
1280Sstevel@tonic-gate#
1298485SPeter.Memishian@Sun.COM# Do the two interfaces share a physical interface?
1300Sstevel@tonic-gate#
1310Sstevel@tonic-gatephysical_comp()
1320Sstevel@tonic-gate{
1330Sstevel@tonic-gate	[ "`get_physical $1`" = "`get_physical $2`" ]
1340Sstevel@tonic-gate}
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate#
1370Sstevel@tonic-gate# in_list op item list
1380Sstevel@tonic-gate#
1390Sstevel@tonic-gate# Is "item" in the given list?  Use "op" to do the test, applying it to
1400Sstevel@tonic-gate# "item" and each member of the list in turn until it returns success.
1410Sstevel@tonic-gate#
1420Sstevel@tonic-gatein_list()
1430Sstevel@tonic-gate{
1440Sstevel@tonic-gate	op=$1
1450Sstevel@tonic-gate	item=$2
1460Sstevel@tonic-gate	shift 2
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate	while [ $# -gt 0 ]; do
1490Sstevel@tonic-gate		$op $item $1 && return 0
1500Sstevel@tonic-gate		shift
1510Sstevel@tonic-gate	done
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate	return 1
1540Sstevel@tonic-gate}
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate#
1578485SPeter.Memishian@Sun.COM# get_groupifname groupname
1588485SPeter.Memishian@Sun.COM#
1598485SPeter.Memishian@Sun.COM# Return the IPMP meta-interface name for the group, if it exists.
1600Sstevel@tonic-gate#
1618485SPeter.Memishian@Sun.COMget_groupifname()
1628485SPeter.Memishian@Sun.COM{
1638485SPeter.Memishian@Sun.COM	/sbin/ipmpstat -gP -o groupname,group | while IFS=: read name ifname; do
1648485SPeter.Memishian@Sun.COM		if [ "$name" = "$1" ]; then
1658485SPeter.Memishian@Sun.COM			echo "$ifname"
1668485SPeter.Memishian@Sun.COM			return
1678485SPeter.Memishian@Sun.COM		fi
1688485SPeter.Memishian@Sun.COM	done
1698485SPeter.Memishian@Sun.COM}
1708485SPeter.Memishian@Sun.COM
1718485SPeter.Memishian@Sun.COM#
1728485SPeter.Memishian@Sun.COM# create_ipmp ifname groupname type
1738485SPeter.Memishian@Sun.COM#
1748485SPeter.Memishian@Sun.COM# Helper function for create_groupifname() that returns zero if it's able
1758485SPeter.Memishian@Sun.COM# to create an IPMP interface of the specified type and place it in the
1768485SPeter.Memishian@Sun.COM# specified group, or non-zero otherwise.
1778485SPeter.Memishian@Sun.COM#
1788485SPeter.Memishian@Sun.COMcreate_ipmp()
1798485SPeter.Memishian@Sun.COM{
1808485SPeter.Memishian@Sun.COM	/sbin/ifconfig $1 >/dev/null 2>&1 && return 1
1818485SPeter.Memishian@Sun.COM	/sbin/ifconfig $1 inet6 >/dev/null 2>&1 && return 1
1828485SPeter.Memishian@Sun.COM	/sbin/ifconfig $1 $3 ipmp group $2 2>/dev/null
1838485SPeter.Memishian@Sun.COM}
1848485SPeter.Memishian@Sun.COM
1858485SPeter.Memishian@Sun.COM#
1868485SPeter.Memishian@Sun.COM# create_groupifname groupname type
1878485SPeter.Memishian@Sun.COM#
1888485SPeter.Memishian@Sun.COM# Create an IPMP meta-interface name for the group.  We only use this
1898485SPeter.Memishian@Sun.COM# function if all of the interfaces in the group failed at boot and there
1908485SPeter.Memishian@Sun.COM# were no /etc/hostname[6].<if> files for the IPMP meta-interface.
1918485SPeter.Memishian@Sun.COM#
1928485SPeter.Memishian@Sun.COMcreate_groupifname()
1938485SPeter.Memishian@Sun.COM{
1948485SPeter.Memishian@Sun.COM	#
1958485SPeter.Memishian@Sun.COM	# This is a horrible way to count from 0 to 999, but in sh and
1968485SPeter.Memishian@Sun.COM	# without necessarily having /usr mounted, what else can we do?
1978485SPeter.Memishian@Sun.COM	#
1988485SPeter.Memishian@Sun.COM	for a in "" 1 2 3 4 5 6 7 8 9; do
1998485SPeter.Memishian@Sun.COM		for b in 0 1 2 3 4 5 6 7 8 9; do
2008485SPeter.Memishian@Sun.COM			for c in 0 1 2 3 4 5 6 7 8 9; do
2018485SPeter.Memishian@Sun.COM				# strip leading zeroes
2028485SPeter.Memishian@Sun.COM				[ "$a" = "" ] && [ "$b" = 0 ] && b=""
2038485SPeter.Memishian@Sun.COM				if create_ipmp ipmp$a$b$c $1 $2; then
2048485SPeter.Memishian@Sun.COM					echo ipmp$a$b$c
2058485SPeter.Memishian@Sun.COM					return
2068485SPeter.Memishian@Sun.COM				fi
2078485SPeter.Memishian@Sun.COM			done
2088485SPeter.Memishian@Sun.COM		done
2098485SPeter.Memishian@Sun.COM	done
2108485SPeter.Memishian@Sun.COM}
2118485SPeter.Memishian@Sun.COM
2128485SPeter.Memishian@Sun.COM#
2138485SPeter.Memishian@Sun.COM# get_hostname_ipmpinfo interface type
2148485SPeter.Memishian@Sun.COM#
2158485SPeter.Memishian@Sun.COM# Return all requested IPMP keywords from hostname file for a given interface.
2160Sstevel@tonic-gate#
2170Sstevel@tonic-gate# Example:
2188485SPeter.Memishian@Sun.COM#	get_hostname_ipmpinfo hme0 inet keyword [ keyword ... ]
2190Sstevel@tonic-gate#
2208485SPeter.Memishian@Sun.COMget_hostname_ipmpinfo()
2210Sstevel@tonic-gate{
2220Sstevel@tonic-gate	case "$2" in
2238485SPeter.Memishian@Sun.COM		inet)	file=/etc/hostname.$1
2240Sstevel@tonic-gate			;;
2258485SPeter.Memishian@Sun.COM		inet6)	file=/etc/hostname6.$1
2260Sstevel@tonic-gate			;;
2270Sstevel@tonic-gate		*)
2280Sstevel@tonic-gate			return
2290Sstevel@tonic-gate			;;
2300Sstevel@tonic-gate	esac
2310Sstevel@tonic-gate
2320Sstevel@tonic-gate	[ -r "$file" ] || return
2330Sstevel@tonic-gate
2348485SPeter.Memishian@Sun.COM	type=$2
2358485SPeter.Memishian@Sun.COM	shift 2
2368485SPeter.Memishian@Sun.COM
2370Sstevel@tonic-gate	#
2388485SPeter.Memishian@Sun.COM	# Read through the hostname file looking for the specified
2398485SPeter.Memishian@Sun.COM	# keywords.  Since there may be several keywords that cancel
2408485SPeter.Memishian@Sun.COM	# each other out, the caller must post-process as appropriate.
2410Sstevel@tonic-gate	#
2420Sstevel@tonic-gate	while read line; do
2430Sstevel@tonic-gate		[ -z "$line" ] && continue
2448485SPeter.Memishian@Sun.COM		/sbin/ifparse -s "$type" $line
2458485SPeter.Memishian@Sun.COM	done < "$file" | while read one two; do
2468485SPeter.Memishian@Sun.COM		for keyword in "$@"; do
2478485SPeter.Memishian@Sun.COM			[ "$one" = "$keyword" ] && echo "$one $two"
2488485SPeter.Memishian@Sun.COM		done
2490Sstevel@tonic-gate	done
2500Sstevel@tonic-gate}
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate#
2530Sstevel@tonic-gate# get_group_for_type interface type list
2540Sstevel@tonic-gate#
2550Sstevel@tonic-gate# Look through the set of hostname files associated with the same physical
2560Sstevel@tonic-gate# interface as "interface", and determine which group they would configure.
2570Sstevel@tonic-gate# Only hostname files associated with the physical interface or logical
2580Sstevel@tonic-gate# interface zero are allowed to set the group.
2590Sstevel@tonic-gate#
2600Sstevel@tonic-gateget_group_for_type()
2610Sstevel@tonic-gate{
2620Sstevel@tonic-gate	physical=`get_physical $1`
2630Sstevel@tonic-gate	type=$2
2640Sstevel@tonic-gate	group=""
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate	#
2670Sstevel@tonic-gate	# The last setting of the group is the one that counts, which is
2680Sstevel@tonic-gate	# the reason for the second while loop.
2690Sstevel@tonic-gate	#
2700Sstevel@tonic-gate	shift 2
2718485SPeter.Memishian@Sun.COM	for ifname in "$@"; do
2728485SPeter.Memishian@Sun.COM		if if_comp "$physical" $ifname; then
2738485SPeter.Memishian@Sun.COM			get_hostname_ipmpinfo $ifname $type group
2740Sstevel@tonic-gate		fi
2750Sstevel@tonic-gate	done | while :; do
2768485SPeter.Memishian@Sun.COM		read keyword grname || {
2770Sstevel@tonic-gate			echo "$group"
2780Sstevel@tonic-gate			break
2790Sstevel@tonic-gate		}
2808485SPeter.Memishian@Sun.COM		group="$grname"
2810Sstevel@tonic-gate	done
2820Sstevel@tonic-gate}
2830Sstevel@tonic-gate
2840Sstevel@tonic-gate#
2858485SPeter.Memishian@Sun.COM# get_group interface
2860Sstevel@tonic-gate#
2878485SPeter.Memishian@Sun.COM# If there is both an inet and inet6 version of an interface, the group
2888485SPeter.Memishian@Sun.COM# could be set in either set of hostname files.  Since inet6 is configured
2898485SPeter.Memishian@Sun.COM# after inet, if there's a setting in both files, inet6 wins.
2900Sstevel@tonic-gate#
2918485SPeter.Memishian@Sun.COMget_group()
2920Sstevel@tonic-gate{
2938485SPeter.Memishian@Sun.COM	group=`get_group_for_type $1 inet6 $inet6_list`
2948485SPeter.Memishian@Sun.COM	[ -z "$group" ] && group=`get_group_for_type $1 inet $inet_list`
2958485SPeter.Memishian@Sun.COM	echo $group
2960Sstevel@tonic-gate}
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate#
29911076SCathy.Zhou@Sun.COM# Given the interface name and the address family (inet or inet6), determine
30011076SCathy.Zhou@Sun.COM# whether this is a VRRP VNIC.
30111076SCathy.Zhou@Sun.COM#
30211076SCathy.Zhou@Sun.COM# This is used to determine whether to bring the interface up
30311076SCathy.Zhou@Sun.COM#
30411076SCathy.Zhou@Sun.COMnot_vrrp_interface() {
30511076SCathy.Zhou@Sun.COM	macaddrtype=`/sbin/dladm show-vnic $1 -o MACADDRTYPE -p 2>/dev/null`
30611076SCathy.Zhou@Sun.COM
30711076SCathy.Zhou@Sun.COM	case "$macaddrtype" in
30811076SCathy.Zhou@Sun.COM	'vrrp'*''$2'')	vrrp=1
30911076SCathy.Zhou@Sun.COM			;;
31011076SCathy.Zhou@Sun.COM        *)		vrrp=0
31111076SCathy.Zhou@Sun.COM			;;
31211076SCathy.Zhou@Sun.COM	esac
31311076SCathy.Zhou@Sun.COM	return $vrrp
31411076SCathy.Zhou@Sun.COM}
31511076SCathy.Zhou@Sun.COM
3160Sstevel@tonic-gate# doDHCPhostname interface
3170Sstevel@tonic-gate# Pass to this function the name of an interface.  It will return
3180Sstevel@tonic-gate# true if one should enable the use of DHCP client-side host name
3190Sstevel@tonic-gate# requests on the interface, and false otherwise.
3200Sstevel@tonic-gate#
3210Sstevel@tonic-gatedoDHCPhostname()
3220Sstevel@tonic-gate{
3230Sstevel@tonic-gate	if [ -f /etc/dhcp.$1 ] && [ -f /etc/hostname.$1 ]; then
3240Sstevel@tonic-gate                set -- `shcat /etc/hostname.$1`
3250Sstevel@tonic-gate                [ $# -eq 2 -a "$1" = "inet" ]
3260Sstevel@tonic-gate                return $?
3270Sstevel@tonic-gate        fi
3280Sstevel@tonic-gate        return 1
3290Sstevel@tonic-gate}
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate#
3320Sstevel@tonic-gate# inet_process_hostname processor [ args ]
3330Sstevel@tonic-gate#
3340Sstevel@tonic-gate# Process an inet hostname file.  The contents of the file
3350Sstevel@tonic-gate# are taken from standard input. Each line is passed
3360Sstevel@tonic-gate# on the command line to the "processor" command.
3370Sstevel@tonic-gate# Command line arguments can be passed to the processor.
3380Sstevel@tonic-gate#
3390Sstevel@tonic-gate# Examples:
3400Sstevel@tonic-gate#	inet_process_hostname /sbin/ifconfig hme0 < /etc/hostname.hme0
3410Sstevel@tonic-gate#
3420Sstevel@tonic-gate#	inet_process_hostname /sbin/ifparse -f < /etc/hostname.hme0
3430Sstevel@tonic-gate#
3440Sstevel@tonic-gate# If there is only line in an hostname file we assume it contains
3450Sstevel@tonic-gate# the old style address which results in the interface being brought up
3468485SPeter.Memishian@Sun.COM# and the netmask and broadcast address being set ($inet_oneline_epilogue).
3470Sstevel@tonic-gate#
34811076SCathy.Zhou@Sun.COM# Note that if the interface is a VRRP interface, do not bring the address
34911076SCathy.Zhou@Sun.COM# up ($inet_oneline_epilogue_no_up).
35011076SCathy.Zhou@Sun.COM#
3510Sstevel@tonic-gate# If there are multiple lines we assume the file contains a list of
3520Sstevel@tonic-gate# commands to the processor with neither the implied bringing up of the
3530Sstevel@tonic-gate# interface nor the setting of the default netmask and broadcast address.
3540Sstevel@tonic-gate#
3550Sstevel@tonic-gate# Return non-zero if any command fails so that the caller may alert
3560Sstevel@tonic-gate# users to errors in the configuration.
3570Sstevel@tonic-gate#
35811076SCathy.Zhou@Sun.COMinet_oneline_epilogue_no_up="netmask + broadcast +"
3598485SPeter.Memishian@Sun.COMinet_oneline_epilogue="netmask + broadcast + up"
3608485SPeter.Memishian@Sun.COM
3610Sstevel@tonic-gateinet_process_hostname()
3620Sstevel@tonic-gate{
3630Sstevel@tonic-gate	if doDHCPhostname $2; then
3640Sstevel@tonic-gate		:
3650Sstevel@tonic-gate	else
3660Sstevel@tonic-gate		#
3670Sstevel@tonic-gate		# Redirecting input from a file results in a sub-shell being
3680Sstevel@tonic-gate		# used, hence this outer loop surrounding the "multiple_lines"
3690Sstevel@tonic-gate		# and "ifcmds" variables.
3700Sstevel@tonic-gate		#
3710Sstevel@tonic-gate		while :; do
3720Sstevel@tonic-gate			multiple_lines=false
3730Sstevel@tonic-gate			ifcmds=""
3740Sstevel@tonic-gate			retval=0
3750Sstevel@tonic-gate
3768485SPeter.Memishian@Sun.COM			while read one rest; do
3770Sstevel@tonic-gate				if [ -n "$ifcmds" ]; then
3780Sstevel@tonic-gate					#
3790Sstevel@tonic-gate					# This handles the first N-1
3800Sstevel@tonic-gate					# lines of a N-line hostname file.
3810Sstevel@tonic-gate					#
3820Sstevel@tonic-gate					$* $ifcmds || retval=$?
3830Sstevel@tonic-gate					multiple_lines=true
3840Sstevel@tonic-gate				fi
3858485SPeter.Memishian@Sun.COM
3868485SPeter.Memishian@Sun.COM				#
3878485SPeter.Memishian@Sun.COM				# Strip out the "ipmp" keyword if it's the
3888485SPeter.Memishian@Sun.COM				# first token, since it's used to control
3898485SPeter.Memishian@Sun.COM				# interface creation, not configuration.
3908485SPeter.Memishian@Sun.COM				#
3918485SPeter.Memishian@Sun.COM				[ "$one" = ipmp ] && one=
3928485SPeter.Memishian@Sun.COM				ifcmds="$one $rest"
3930Sstevel@tonic-gate			done
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate			#
3960Sstevel@tonic-gate			# If the hostname file is empty or consists of only
3970Sstevel@tonic-gate			# blank lines, break out of the outer loop without
3980Sstevel@tonic-gate			# configuring the newly plumbed interface.
3990Sstevel@tonic-gate			#
4000Sstevel@tonic-gate			[ -z "$ifcmds" ] && return $retval
4010Sstevel@tonic-gate			if [ $multiple_lines = false ]; then
40211076SCathy.Zhou@Sun.COM				#
4038485SPeter.Memishian@Sun.COM				# The traditional one-line hostname file.
40411076SCathy.Zhou@Sun.COM				# Note that we only bring it up if the
40511076SCathy.Zhou@Sun.COM				# interface is not a VRRP VNIC.
40611076SCathy.Zhou@Sun.COM				#
40711076SCathy.Zhou@Sun.COM				if not_vrrp_interface $2 $3; then
40811076SCathy.Zhou@Sun.COM					estr="$inet_oneline_epilogue"
40911076SCathy.Zhou@Sun.COM				else
41011076SCathy.Zhou@Sun.COM					estr="$inet_oneline_epilogue_no_up"
41111076SCathy.Zhou@Sun.COM				fi
41211076SCathy.Zhou@Sun.COM				ifcmds="$ifcmds $estr"
4130Sstevel@tonic-gate			fi
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate			#
4160Sstevel@tonic-gate			# This handles either the single-line case or
4170Sstevel@tonic-gate			# the last line of the N-line case.
4180Sstevel@tonic-gate			#
4190Sstevel@tonic-gate			$* $ifcmds || return $?
4200Sstevel@tonic-gate			return $retval
4210Sstevel@tonic-gate		done
4220Sstevel@tonic-gate	fi
4230Sstevel@tonic-gate}
4240Sstevel@tonic-gate
4250Sstevel@tonic-gate#
4260Sstevel@tonic-gate# inet6_process_hostname processor [ args ]
4270Sstevel@tonic-gate#
4280Sstevel@tonic-gate# Process an inet6 hostname file.  The contents of the file
4290Sstevel@tonic-gate# are taken from standard input. Each line is passed
4300Sstevel@tonic-gate# on the command line to the "processor" command.
4310Sstevel@tonic-gate# Command line arguments can be passed to the processor.
4320Sstevel@tonic-gate#
4330Sstevel@tonic-gate# Examples:
4340Sstevel@tonic-gate#	inet6_process_hostname /sbin/ifconfig hme0 inet6 < /etc/hostname6.hme0
4350Sstevel@tonic-gate#
4360Sstevel@tonic-gate#	inet6_process_hostname /sbin/ifparse -f inet6 < /etc/hostname6.hme0
4370Sstevel@tonic-gate#
4380Sstevel@tonic-gate# Return non-zero if any of the commands fail so that the caller may alert
4390Sstevel@tonic-gate# users to errors in the configuration.
4400Sstevel@tonic-gate#
4410Sstevel@tonic-gateinet6_process_hostname()
4420Sstevel@tonic-gate{
4430Sstevel@tonic-gate    	retval=0
4448485SPeter.Memishian@Sun.COM	while read one rest; do
4458485SPeter.Memishian@Sun.COM		#
4468485SPeter.Memishian@Sun.COM	    	# See comment in inet_process_hostname for details.
4478485SPeter.Memishian@Sun.COM	        #
4488485SPeter.Memishian@Sun.COM		[ "$one" = ipmp ] && one=
4498485SPeter.Memishian@Sun.COM		ifcmds="$one $rest"
4508485SPeter.Memishian@Sun.COM
4510Sstevel@tonic-gate		if [ -n "$ifcmds" ]; then
4520Sstevel@tonic-gate			$* $ifcmds || retval=$?
4530Sstevel@tonic-gate		fi
4540Sstevel@tonic-gate	done
4550Sstevel@tonic-gate	return $retval
4560Sstevel@tonic-gate}
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate#
4598485SPeter.Memishian@Sun.COM# Process interfaces that failed to plumb.  Find the IPMP meta-interface
4608485SPeter.Memishian@Sun.COM# that should host the addresses.  For IPv6, only static addresses defined
4618485SPeter.Memishian@Sun.COM# in hostname6 files are moved, autoconfigured addresses are not moved.
4620Sstevel@tonic-gate#
4630Sstevel@tonic-gate# Example:
4640Sstevel@tonic-gate#	move_addresses inet6
4650Sstevel@tonic-gate#
4660Sstevel@tonic-gatemove_addresses()
4670Sstevel@tonic-gate{
4680Sstevel@tonic-gate	type="$1"
4690Sstevel@tonic-gate	eval "failed=\"\$${type}_failed\""
4700Sstevel@tonic-gate	eval "list=\"\$${type}_list\""
4718485SPeter.Memishian@Sun.COM	process_func="${type}_process_hostname"
4720Sstevel@tonic-gate	processed=""
4730Sstevel@tonic-gate
4740Sstevel@tonic-gate	if [ "$type" = inet ]; then
4758485SPeter.Memishian@Sun.COM	        typedesc="IPv4"
4760Sstevel@tonic-gate		zaddr="0.0.0.0"
4770Sstevel@tonic-gate		hostpfx="/etc/hostname"
4780Sstevel@tonic-gate	else
4798485SPeter.Memishian@Sun.COM	        typedesc="IPv6"
4800Sstevel@tonic-gate		zaddr="::"
4810Sstevel@tonic-gate		hostpfx="/etc/hostname6"
4820Sstevel@tonic-gate	fi
4830Sstevel@tonic-gate
4848485SPeter.Memishian@Sun.COM	echo "Moving addresses from missing ${typedesc} interface(s):\c" \
4858485SPeter.Memishian@Sun.COM	    >/dev/msglog
4868485SPeter.Memishian@Sun.COM
4878485SPeter.Memishian@Sun.COM	for ifname in $failed; do
4888485SPeter.Memishian@Sun.COM		in_list if_comp $ifname $processed && continue
4890Sstevel@tonic-gate
4908485SPeter.Memishian@Sun.COM		group=`get_group $ifname`
4918485SPeter.Memishian@Sun.COM		if [ -z "$group" ]; then
4928485SPeter.Memishian@Sun.COM			in_list physical_comp $ifname $processed || {
4938485SPeter.Memishian@Sun.COM				echo " $ifname (not moved -- not" \
4948485SPeter.Memishian@Sun.COM				    "in an IPMP group)\c" >/dev/msglog
4958485SPeter.Memishian@Sun.COM				processed="$processed $ifname"
4960Sstevel@tonic-gate			}
4970Sstevel@tonic-gate			continue
4980Sstevel@tonic-gate		fi
4998485SPeter.Memishian@Sun.COM
5008485SPeter.Memishian@Sun.COM		#
5018485SPeter.Memishian@Sun.COM		# Lookup the IPMP meta-interface name.  If one doesn't exist,
5028485SPeter.Memishian@Sun.COM		# create it.
5038485SPeter.Memishian@Sun.COM		#
5048485SPeter.Memishian@Sun.COM		grifname=`get_groupifname $group`
5058485SPeter.Memishian@Sun.COM		[ -z "$grifname" ] && grifname=`create_groupifname $group $type`
5068485SPeter.Memishian@Sun.COM
5070Sstevel@tonic-gate		#
5080Sstevel@tonic-gate		# The hostname files are processed twice.  In the first
50910649SPeter.Memishian@Sun.COM		# pass, we are looking for all commands that apply to the
51010649SPeter.Memishian@Sun.COM		# non-additional interface address.  These may be
51110649SPeter.Memishian@Sun.COM		# scattered over several files.  We won't know whether the
51210649SPeter.Memishian@Sun.COM		# address represents a failover address or not until we've
51310649SPeter.Memishian@Sun.COM		# read all the files associated with the interface.
5148485SPeter.Memishian@Sun.COM		#
5150Sstevel@tonic-gate		# In the first pass through the hostname files, all
51610649SPeter.Memishian@Sun.COM		# additional logical interface commands are removed.  The
51710649SPeter.Memishian@Sun.COM		# remaining commands are concatenated together and passed
51810649SPeter.Memishian@Sun.COM		# to ifparse to determine whether the non-additional
51910649SPeter.Memishian@Sun.COM		# logical interface address is a failover address.  If it
52010649SPeter.Memishian@Sun.COM		# as a failover address, the address may not be the first
52110649SPeter.Memishian@Sun.COM		# item on the line, so we can't just substitute "addif"
52210649SPeter.Memishian@Sun.COM		# for "set".  We prepend an "addif $zaddr" command, and
52310649SPeter.Memishian@Sun.COM		# let the embedded "set" command set the address later.
5240Sstevel@tonic-gate		#
5250Sstevel@tonic-gate		/sbin/ifparse -f $type `
5268485SPeter.Memishian@Sun.COM			for item in $list; do
5278485SPeter.Memishian@Sun.COM				if_comp $ifname $item && $process_func \
5288485SPeter.Memishian@Sun.COM				    /sbin/ifparse $type < $hostpfx.$item
5298485SPeter.Memishian@Sun.COM			done | while read three four; do
5308485SPeter.Memishian@Sun.COM				[ "$three" != addif ] && echo "$three $four \c"
5318485SPeter.Memishian@Sun.COM			done` | while read one two; do
5328485SPeter.Memishian@Sun.COM				[ -z "$one" ] && continue
5338485SPeter.Memishian@Sun.COM				[ "$one $two" = "$inet_oneline_epilogue" ] && \
5348485SPeter.Memishian@Sun.COM				    continue
5358485SPeter.Memishian@Sun.COM				line="addif $zaddr $one $two"
5368485SPeter.Memishian@Sun.COM				/sbin/ifconfig $grifname $type $line >/dev/null
5378485SPeter.Memishian@Sun.COM			done
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate		#
5400Sstevel@tonic-gate		# In the second pass, look for the the "addif" commands
5410Sstevel@tonic-gate		# that configure additional failover addresses.  Addif
5420Sstevel@tonic-gate		# commands are not valid in logical interface hostname
5430Sstevel@tonic-gate		# files.
5440Sstevel@tonic-gate		#
5458485SPeter.Memishian@Sun.COM		if [ "$ifname" = "`get_physical $ifname`" ]; then
5468485SPeter.Memishian@Sun.COM			$process_func /sbin/ifparse -f $type < $hostpfx.$ifname \
5478485SPeter.Memishian@Sun.COM			| while read one two; do
5488485SPeter.Memishian@Sun.COM				[ "$one" = addif ] && \
5498485SPeter.Memishian@Sun.COM					/sbin/ifconfig $grifname $type \
5508485SPeter.Memishian@Sun.COM				    	    addif $two >/dev/null
5510Sstevel@tonic-gate			done
5520Sstevel@tonic-gate		fi
5530Sstevel@tonic-gate
5548485SPeter.Memishian@Sun.COM		in_list physical_comp $ifname $processed || {
5558485SPeter.Memishian@Sun.COM			processed="$processed $ifname"
55610649SPeter.Memishian@Sun.COM			echo " $ifname (moved to $grifname)\c" > /dev/msglog
5570Sstevel@tonic-gate		}
5588485SPeter.Memishian@Sun.COM	done
5598485SPeter.Memishian@Sun.COM	echo "." >/dev/msglog
5608485SPeter.Memishian@Sun.COM}
5618485SPeter.Memishian@Sun.COM
5628485SPeter.Memishian@Sun.COM#
56312748SSowmini.Varadhan@oracle.COM# ipadm_from_gz_if ifname
56412748SSowmini.Varadhan@oracle.COM#
56512748SSowmini.Varadhan@oracle.COM# Return true if we are in a non-global zone and Layer-3 protection of
56612748SSowmini.Varadhan@oracle.COM# IP addresses is being enforced on the interface by the global zone
56712748SSowmini.Varadhan@oracle.COM#
56812748SSowmini.Varadhan@oracle.COMipadm_from_gz_if()
56912748SSowmini.Varadhan@oracle.COM{
57012748SSowmini.Varadhan@oracle.COM	pif=`/sbin/ipadm show-if -o persistent -p $1 2>/dev/null | egrep '4|6'`
57112748SSowmini.Varadhan@oracle.COM	if smf_is_globalzone || ![[ $pif == *4* || $pif == *6* ]]; then
57212748SSowmini.Varadhan@oracle.COM		return 1
57312748SSowmini.Varadhan@oracle.COM	else
57412748SSowmini.Varadhan@oracle.COM		#
57512748SSowmini.Varadhan@oracle.COM		# In the non-global zone, plumb the interface to show current
57612748SSowmini.Varadhan@oracle.COM		# flags and check if Layer-3 protection has been enforced by
57712748SSowmini.Varadhan@oracle.COM		# the global zone. Note that this function may return
57812748SSowmini.Varadhan@oracle.COM		# with a plumbed interface. Ideally, we would not have to
57912748SSowmini.Varadhan@oracle.COM		# plumb the interface to check l3protect, but since we
58012748SSowmini.Varadhan@oracle.COM		# the `allowed-ips' datalink property cannot currently be
58112748SSowmini.Varadhan@oracle.COM		# examined in any other way from the non-global zone, we
58212748SSowmini.Varadhan@oracle.COM		# resort to plumbing the interface
58312748SSowmini.Varadhan@oracle.COM		#
58412748SSowmini.Varadhan@oracle.COM		/sbin/ifconfig $1 plumb > /dev/null 2>&1
58512748SSowmini.Varadhan@oracle.COM		l3protect=`/sbin/ipadm show-if -o current -p $1|grep -c 'Z'`
58612748SSowmini.Varadhan@oracle.COM		if [ $l3protect = 0 ]; then
58712748SSowmini.Varadhan@oracle.COM			return 1
58812748SSowmini.Varadhan@oracle.COM		else
58912748SSowmini.Varadhan@oracle.COM			return 0
59012748SSowmini.Varadhan@oracle.COM		fi
59112748SSowmini.Varadhan@oracle.COM	fi
59212748SSowmini.Varadhan@oracle.COM}
59312748SSowmini.Varadhan@oracle.COM
59412748SSowmini.Varadhan@oracle.COM#
5958485SPeter.Memishian@Sun.COM# if_configure type class interface_list
5968485SPeter.Memishian@Sun.COM#
5978485SPeter.Memishian@Sun.COM# Configure all of the interfaces of type `type' (e.g., "inet6") in
5988485SPeter.Memishian@Sun.COM# `interface_list' according to their /etc/hostname[6].* files.  `class'
5998485SPeter.Memishian@Sun.COM# describes the class of interface (e.g., "IPMP"), as a diagnostic aid.
6008485SPeter.Memishian@Sun.COM# For inet6 interfaces, the interface is also brought up.
6018485SPeter.Memishian@Sun.COM#
6028485SPeter.Memishian@Sun.COMif_configure()
6038485SPeter.Memishian@Sun.COM{
6048485SPeter.Memishian@Sun.COM	fail=
6058485SPeter.Memishian@Sun.COM	type=$1
6068485SPeter.Memishian@Sun.COM	class=$2
6078485SPeter.Memishian@Sun.COM	process_func=${type}_process_hostname
6088485SPeter.Memishian@Sun.COM	shift 2
6098485SPeter.Memishian@Sun.COM
6108485SPeter.Memishian@Sun.COM	if [ "$type" = inet ]; then
6118485SPeter.Memishian@Sun.COM	        desc="IPv4"
6128485SPeter.Memishian@Sun.COM		hostpfx="/etc/hostname"
6138485SPeter.Memishian@Sun.COM	else
6148485SPeter.Memishian@Sun.COM	        desc="IPv6"
6158485SPeter.Memishian@Sun.COM		hostpfx="/etc/hostname6"
6168485SPeter.Memishian@Sun.COM	fi
6178485SPeter.Memishian@Sun.COM	[ -n "$class" ] && desc="$class $desc"
6188485SPeter.Memishian@Sun.COM
6198485SPeter.Memishian@Sun.COM	echo "configuring $desc interfaces:\c"
6208485SPeter.Memishian@Sun.COM	while [ $# -gt 0 ]; do
6218485SPeter.Memishian@Sun.COM		$process_func /sbin/ifconfig $1 $type < $hostpfx.$1 >/dev/null
6228485SPeter.Memishian@Sun.COM		if [ $? != 0 ]; then
62312748SSowmini.Varadhan@oracle.COM			ipadm_from_gz_if $1
62412748SSowmini.Varadhan@oracle.COM			if [ $? != 0 ]; then
62512748SSowmini.Varadhan@oracle.COM				fail="$fail $1"
62612748SSowmini.Varadhan@oracle.COM			fi
6278485SPeter.Memishian@Sun.COM		elif [ "$type" = inet6 ]; then
62811076SCathy.Zhou@Sun.COM			#
62911076SCathy.Zhou@Sun.COM			# only bring the interface up if it is not a
63011076SCathy.Zhou@Sun.COM			# VRRP VNIC
63111076SCathy.Zhou@Sun.COM			#
63211076SCathy.Zhou@Sun.COM			if not_vrrp_interface $1 $type; then
63311076SCathy.Zhou@Sun.COM			    	/sbin/ifconfig $1 inet6 up || fail="$fail $1"
63411076SCathy.Zhou@Sun.COM			fi
6358485SPeter.Memishian@Sun.COM		fi
6368485SPeter.Memishian@Sun.COM		echo " $1\c"
6370Sstevel@tonic-gate		shift
6380Sstevel@tonic-gate	done
6390Sstevel@tonic-gate	echo "."
6408485SPeter.Memishian@Sun.COM
6418485SPeter.Memishian@Sun.COM	[ -n "$fail" ] && warn_failed_ifs "configure $desc" "$fail"
6420Sstevel@tonic-gate}
6435895Syz147064
6445895Syz147064#
6455895Syz147064# net_reconfigure is called from the network/physical service (by the
6465895Syz147064# net-physical and net-nwam method scripts) to perform tasks that only
6475895Syz147064# need to be done during a reconfigure boot.  This needs to be
6485895Syz147064# isolated in a function since network/physical has two instances
6495895Syz147064# (default and nwam) that have distinct method scripts that each need
6505895Syz147064# to do these things.
6515895Syz147064#
6525895Syz147064net_reconfigure ()
6535895Syz147064{
6545895Syz147064	#
6555895Syz147064	# Is this a reconfigure boot?  If not, then there's nothing
6565895Syz147064	# for us to do.
6575895Syz147064	#
6589682SCathy.Zhou@Sun.COM	reconfig=`svcprop -c -p system/reconfigure \
6599682SCathy.Zhou@Sun.COM	    system/svc/restarter:default 2>/dev/null`
6607645Sjames.d.carlson@sun.com	if [ $? -ne 0 -o "$reconfig" = false ]; then
6615895Syz147064		return 0
6625895Syz147064	fi
6635895Syz147064
6645895Syz147064	#
6655895Syz147064	# Ensure that the datalink-management service is running since
6665895Syz147064	# manifest-import has not yet run for a first boot after
6675895Syz147064	# upgrade.  We wouldn't need to do that if manifest-import ran
6685895Syz147064	# earlier in boot, since there is an explicit dependency
6695895Syz147064	# between datalink-management and network/physical.
6705895Syz147064	#
6715895Syz147064	svcadm enable -ts network/datalink-management:default
6725895Syz147064
6735895Syz147064	#
6745895Syz147064	# There is a bug in SMF which causes the svcadm command above
6755895Syz147064	# to exit prematurely (with an error code of 3) before having
6765895Syz147064	# waited for the service to come online after having enabled
6775895Syz147064	# it.  Until that bug is fixed, we need to have the following
6785895Syz147064	# loop to explicitly wait for the service to come online.
6795895Syz147064	#
6805895Syz147064	i=0
6815895Syz147064	while [ $i -lt 30 ]; do
6825895Syz147064		i=`expr $i + 1`
6835895Syz147064		sleep 1
6845895Syz147064		state=`svcprop -p restarter/state \
6855895Syz147064		    network/datalink-management:default 2>/dev/null`
6865895Syz147064		if [ $? -ne 0 ]; then
6875895Syz147064			continue
6885895Syz147064		elif [ "$state" = "online" ]; then
6895895Syz147064			break
6905895Syz147064		fi
6915895Syz147064	done
6925895Syz147064	if [ "$state" != "online" ]; then
6935895Syz147064		echo "The network/datalink-management service \c"
6945895Syz147064		echo "did not come online."
6955895Syz147064		return 1
6965895Syz147064	fi
6975895Syz147064
6985895Syz147064	#
6995895Syz147064	# Initialize the set of physical links, and validate and
7005895Syz147064	# remove all the physical links which were removed during the
7015895Syz147064	# system shutdown.
7025895Syz147064	#
7035895Syz147064	/sbin/dladm init-phys
7045895Syz147064	return 0
7055895Syz147064}
70610491SRishi.Srivatsavai@Sun.COM
70710491SRishi.Srivatsavai@Sun.COM#
70810491SRishi.Srivatsavai@Sun.COM# Check for use of the default "Port VLAN Identifier" (PVID) -- VLAN 1.
70910491SRishi.Srivatsavai@Sun.COM# If there is one for a given interface, then warn the user and force the
71010491SRishi.Srivatsavai@Sun.COM# PVID to zero (if it's not already set).  We do this by generating a list
71110491SRishi.Srivatsavai@Sun.COM# of interfaces with VLAN 1 in use first, and then parsing out the
71210491SRishi.Srivatsavai@Sun.COM# corresponding base datalink entries to check for ones without a
71310491SRishi.Srivatsavai@Sun.COM# "default_tag" property.
71410491SRishi.Srivatsavai@Sun.COM#
71510491SRishi.Srivatsavai@Sun.COMupdate_pvid()
71610491SRishi.Srivatsavai@Sun.COM{
71710491SRishi.Srivatsavai@Sun.COM	datalink=/etc/dladm/datalink.conf
71810491SRishi.Srivatsavai@Sun.COM
71910491SRishi.Srivatsavai@Sun.COM	(
72010491SRishi.Srivatsavai@Sun.COM		# Find datalinks using VLAN 1 explicitly
72110491SRishi.Srivatsavai@Sun.COM		# configured by dladm
72210491SRishi.Srivatsavai@Sun.COM		/usr/bin/nawk '
72310491SRishi.Srivatsavai@Sun.COM			/^#/ || NF < 2 { next }
72410491SRishi.Srivatsavai@Sun.COM			{ linkdata[$1]=$2; }
72510491SRishi.Srivatsavai@Sun.COM			/;vid=int,1;/ {
72610491SRishi.Srivatsavai@Sun.COM				sub(/.*;linkover=int,/, "", $2);
72710491SRishi.Srivatsavai@Sun.COM				sub(/;.*/, "", $2);
72810491SRishi.Srivatsavai@Sun.COM				link=linkdata[$2];
72910491SRishi.Srivatsavai@Sun.COM				sub(/name=string,/, "", link);
73010491SRishi.Srivatsavai@Sun.COM				sub(/;.*/, "", link);
73110491SRishi.Srivatsavai@Sun.COM				print link;
73210491SRishi.Srivatsavai@Sun.COM			}' $datalink
73310491SRishi.Srivatsavai@Sun.COM	) | ( /usr/bin/sort -u; echo END; cat $datalink ) | /usr/bin/nawk '
73410491SRishi.Srivatsavai@Sun.COM	    /^END$/ { state=1; }
73510491SRishi.Srivatsavai@Sun.COM	    state == 0 { usingpvid[++nusingpvid]=$1; next; }
73610491SRishi.Srivatsavai@Sun.COM	    /^#/ || NF < 2 { next; }
73710491SRishi.Srivatsavai@Sun.COM	    {
73810491SRishi.Srivatsavai@Sun.COM		# If it is already present and has a tag set,
73910491SRishi.Srivatsavai@Sun.COM		# then believe it.
74010491SRishi.Srivatsavai@Sun.COM		if (!match($2, /;default_tag=/))
74110491SRishi.Srivatsavai@Sun.COM			next;
74210491SRishi.Srivatsavai@Sun.COM		sub(/name=string,/, "", $2);
74310491SRishi.Srivatsavai@Sun.COM		sub(/;.*/, "", $2);
74410491SRishi.Srivatsavai@Sun.COM		for (i = 1; i <= nusingpvid; i++) {
74510491SRishi.Srivatsavai@Sun.COM			if (usingpvid[i] == $2)
74610491SRishi.Srivatsavai@Sun.COM				usingpvid[i]="";
74710491SRishi.Srivatsavai@Sun.COM		}
74810491SRishi.Srivatsavai@Sun.COM	    }
74910491SRishi.Srivatsavai@Sun.COM	    END {
75010491SRishi.Srivatsavai@Sun.COM		for (i = 1; i <= nusingpvid; i++) {
75110491SRishi.Srivatsavai@Sun.COM			if (usingpvid[i] != "") {
75210491SRishi.Srivatsavai@Sun.COM				printf("Warning: default VLAN tag set to 0" \
75310491SRishi.Srivatsavai@Sun.COM				    " on %s\n", usingpvid[i]);
75410491SRishi.Srivatsavai@Sun.COM				cmd=sprintf("dladm set-linkprop -p " \
75510491SRishi.Srivatsavai@Sun.COM				    "default_tag=0 %s\n", usingpvid[i]);
75610491SRishi.Srivatsavai@Sun.COM				system(cmd);
75710491SRishi.Srivatsavai@Sun.COM			}
75810491SRishi.Srivatsavai@Sun.COM		}
75910491SRishi.Srivatsavai@Sun.COM	    }'
76010491SRishi.Srivatsavai@Sun.COM}
76111767SAnurag.Maskey@Sun.COM
76211767SAnurag.Maskey@Sun.COM#
76311767SAnurag.Maskey@Sun.COM# service_exists fmri
76411767SAnurag.Maskey@Sun.COM#
76511767SAnurag.Maskey@Sun.COM# returns success (0) if the service exists, 1 otherwise.
76611767SAnurag.Maskey@Sun.COM#
76711767SAnurag.Maskey@Sun.COMservice_exists()
76811767SAnurag.Maskey@Sun.COM{
76911767SAnurag.Maskey@Sun.COM	/usr/sbin/svccfg -s $1 listpg > /dev/null 2>&1
77011767SAnurag.Maskey@Sun.COM	if [ $? -eq 0 ]; then
77111767SAnurag.Maskey@Sun.COM		return 0;
77211767SAnurag.Maskey@Sun.COM	fi
77311767SAnurag.Maskey@Sun.COM	return 1;
77411767SAnurag.Maskey@Sun.COM}
77511767SAnurag.Maskey@Sun.COM
77611767SAnurag.Maskey@Sun.COM#
77711767SAnurag.Maskey@Sun.COM# service_is_enabled fmri
77811767SAnurag.Maskey@Sun.COM#
77911767SAnurag.Maskey@Sun.COM# returns success (0) if the service is enabled (permanently or
78011767SAnurag.Maskey@Sun.COM# temporarily), 1 otherwise.
78111767SAnurag.Maskey@Sun.COM#
78211767SAnurag.Maskey@Sun.COMservice_is_enabled()
78311767SAnurag.Maskey@Sun.COM{
78411767SAnurag.Maskey@Sun.COM	#
78511767SAnurag.Maskey@Sun.COM	# The -c option must be specified to use the composed view
78611767SAnurag.Maskey@Sun.COM	# because the general/enabled property takes immediate effect.
78711767SAnurag.Maskey@Sun.COM	# See Example 2 in svcprop(1).
78811767SAnurag.Maskey@Sun.COM	#
78911767SAnurag.Maskey@Sun.COM	# Look at the general_ovr/enabled (if it is present) first to
79011767SAnurag.Maskey@Sun.COM	# determine the temporarily enabled state.
79111767SAnurag.Maskey@Sun.COM	#
79211767SAnurag.Maskey@Sun.COM	tstate=`/usr/bin/svcprop -c -p general_ovr/enabled $1 2>/dev/null`
79311767SAnurag.Maskey@Sun.COM	if [ $? -eq 0 ]; then
79411767SAnurag.Maskey@Sun.COM		[ "$tstate" = "true" ] && return 0
79511767SAnurag.Maskey@Sun.COM		return 1
79611767SAnurag.Maskey@Sun.COM	fi
79711767SAnurag.Maskey@Sun.COM
79811767SAnurag.Maskey@Sun.COM        state=`/usr/bin/svcprop -c -p general/enabled $1 2>/dev/null`
79911767SAnurag.Maskey@Sun.COM	[ "$state" = "true" ] && return 0
80011767SAnurag.Maskey@Sun.COM	return 1
80111767SAnurag.Maskey@Sun.COM}
80211767SAnurag.Maskey@Sun.COM
80311767SAnurag.Maskey@Sun.COM#
80411767SAnurag.Maskey@Sun.COM# is_valid_v4addr addr
80511767SAnurag.Maskey@Sun.COM#
80611767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv4 address is given, 1 otherwise.
80711767SAnurag.Maskey@Sun.COM#
80811767SAnurag.Maskey@Sun.COMis_valid_v4addr()
80911767SAnurag.Maskey@Sun.COM{
81011767SAnurag.Maskey@Sun.COM	echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \
81111767SAnurag.Maskey@Sun.COM	$1 !~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
81211767SAnurag.Maskey@Sun.COM	(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \
81311767SAnurag.Maskey@Sun.COM	{ exit 1 }'
81411767SAnurag.Maskey@Sun.COM	return $?
81511767SAnurag.Maskey@Sun.COM}
81611767SAnurag.Maskey@Sun.COM
81711767SAnurag.Maskey@Sun.COM#
81811767SAnurag.Maskey@Sun.COM# is_valid_v6addr addr
81911767SAnurag.Maskey@Sun.COM#
82011767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv6 address is given, 1 otherwise.
82111767SAnurag.Maskey@Sun.COM#
82211767SAnurag.Maskey@Sun.COMis_valid_v6addr()
82311767SAnurag.Maskey@Sun.COM{
82411767SAnurag.Maskey@Sun.COM	echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \
82511767SAnurag.Maskey@Sun.COM	# 1:2:3:4:5:6:7:8
82611767SAnurag.Maskey@Sun.COM	$1 !~ /^([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/ &&
82711767SAnurag.Maskey@Sun.COM	# 1:2:3::6:7:8
82811767SAnurag.Maskey@Sun.COM	$1 !~ /^([a-fA-F0-9]{1,4}:){0,6}:([a-fA-F0-9]{1,4}:){0,6}\
82911767SAnurag.Maskey@Sun.COM	[a-fA-F0-9]{1,4}$/ &&
83011767SAnurag.Maskey@Sun.COM	# 1:2:3::
83111767SAnurag.Maskey@Sun.COM	$1 !~ /^([a-fA-F0-9]{1,4}:){0,7}:$/ &&
83211767SAnurag.Maskey@Sun.COM	# ::7:8
83311767SAnurag.Maskey@Sun.COM	$1 !~ /^:(:[a-fA-F0-9]{1,4}){0,6}:[a-fA-F0-9]{1,4}$/ &&
83411767SAnurag.Maskey@Sun.COM	# ::f:1.2.3.4
83511767SAnurag.Maskey@Sun.COM	$1 !~ /^:(:[a-fA-F0-9]{1,4}){0,5}:\
83611767SAnurag.Maskey@Sun.COM	((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
83711767SAnurag.Maskey@Sun.COM	(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ &&
83811767SAnurag.Maskey@Sun.COM	# a:b:c:d:e:f:1.2.3.4
83911767SAnurag.Maskey@Sun.COM	$1 !~ /^([a-fA-F0-9]{1,4}:){6}\
84011767SAnurag.Maskey@Sun.COM	((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
84111767SAnurag.Maskey@Sun.COM	(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \
84211767SAnurag.Maskey@Sun.COM	{ exit 1 }'
84311767SAnurag.Maskey@Sun.COM	return $?
84411767SAnurag.Maskey@Sun.COM}
84511767SAnurag.Maskey@Sun.COM
84611767SAnurag.Maskey@Sun.COM#
84711767SAnurag.Maskey@Sun.COM# is_valid_addr addr
84811767SAnurag.Maskey@Sun.COM#
84911767SAnurag.Maskey@Sun.COM# Returns 0 if a valid IPv4 or IPv6 address is given, 1 otherwise.
85011767SAnurag.Maskey@Sun.COM#
85111767SAnurag.Maskey@Sun.COMis_valid_addr()
85211767SAnurag.Maskey@Sun.COM{
85311767SAnurag.Maskey@Sun.COM	is_valid_v4addr $1 || is_valid_v6addr $1
85411767SAnurag.Maskey@Sun.COM}
85511767SAnurag.Maskey@Sun.COM
85611767SAnurag.Maskey@Sun.COM#
85711767SAnurag.Maskey@Sun.COM# nwam_get_loc_prop location property
85811767SAnurag.Maskey@Sun.COM#
85911767SAnurag.Maskey@Sun.COM# echoes the value of the property for the given location
86011767SAnurag.Maskey@Sun.COM# return:
86111767SAnurag.Maskey@Sun.COM#	0 => property is set
86211767SAnurag.Maskey@Sun.COM#	1 => property is not set
86311767SAnurag.Maskey@Sun.COM#
86411767SAnurag.Maskey@Sun.COMnwam_get_loc_prop()
86511767SAnurag.Maskey@Sun.COM{
86611767SAnurag.Maskey@Sun.COM	value=`/usr/sbin/nwamcfg "select loc $1; get -V $2" 2>/dev/null`
86711767SAnurag.Maskey@Sun.COM	rtn=$?
86811767SAnurag.Maskey@Sun.COM	echo $value
86911767SAnurag.Maskey@Sun.COM	return $rtn
87011767SAnurag.Maskey@Sun.COM}
87112861SRenee.Sommerfeld@Oracle.COM
87212861SRenee.Sommerfeld@Oracle.COM#
87312861SRenee.Sommerfeld@Oracle.COM# nwam_get_loc_list_prop location property
87412861SRenee.Sommerfeld@Oracle.COM#
87512861SRenee.Sommerfeld@Oracle.COM# echoes a space-separated list of the property values for the given location
87612861SRenee.Sommerfeld@Oracle.COM# return:
87712861SRenee.Sommerfeld@Oracle.COM#	0 => property is set
87812861SRenee.Sommerfeld@Oracle.COM#	1 => property is not set
87912861SRenee.Sommerfeld@Oracle.COM#
88012861SRenee.Sommerfeld@Oracle.COMnwam_get_loc_list_prop()
88112861SRenee.Sommerfeld@Oracle.COM{
88212861SRenee.Sommerfeld@Oracle.COM	clist=`/usr/sbin/nwamcfg "select loc $1; get -V $2" 2>/dev/null`
88312861SRenee.Sommerfeld@Oracle.COM	rtn=$?
88412861SRenee.Sommerfeld@Oracle.COM	#
88512861SRenee.Sommerfeld@Oracle.COM	# nwamcfg gives us a comma-separated list;
88612861SRenee.Sommerfeld@Oracle.COM	# need to convert commas to spaces.
88712861SRenee.Sommerfeld@Oracle.COM	#
88812861SRenee.Sommerfeld@Oracle.COM	slist=`echo $clist | sed -e s/","/" "/g`
88912861SRenee.Sommerfeld@Oracle.COM	echo $slist
89012861SRenee.Sommerfeld@Oracle.COM	return $rtn
89112861SRenee.Sommerfeld@Oracle.COM}
892