xref: /onnv-gate/usr/src/cmd/svc/milestone/net-svc (revision 11262:b7ebfbf2359e)
10Sstevel@tonic-gate#!/sbin/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
61573Sdp# Common Development and Distribution License (the "License").
71573Sdp# 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#
23*11262SRajagopal.Andra@Sun.COM# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate# Use is subject to license terms.
250Sstevel@tonic-gate#
260Sstevel@tonic-gate
270Sstevel@tonic-gate#
280Sstevel@tonic-gate# This is third phase of TCP/IP startup/configuration.  This script
29*11262SRajagopal.Andra@Sun.COM# runs after the NIS startup script.  We run things here that may
30*11262SRajagopal.Andra@Sun.COM# depend on NIS maps.
310Sstevel@tonic-gate#
320Sstevel@tonic-gate
331573Sdp. /lib/svc/share/smf_include.sh
341573Sdp
350Sstevel@tonic-gatecase "$1" in
360Sstevel@tonic-gate'start')
370Sstevel@tonic-gate	#
383448Sdh155122	# In a shared-IP zone we need this service to be up, but all of the
393448Sdh155122	# work it tries to do is irrelevant (and will actually lead to the
403448Sdh155122	# service failing if we try to do it), so just bail out.
413448Sdh155122	# In the global zone and exclusive-IP zones we proceed.
420Sstevel@tonic-gate	#
433448Sdh155122	smf_configure_ip || exit 0
440Sstevel@tonic-gate	;; # Fall through -- rest of script is the initialization code
450Sstevel@tonic-gate
460Sstevel@tonic-gate'stop')
470Sstevel@tonic-gate	exit 0
480Sstevel@tonic-gate	;;
490Sstevel@tonic-gate
500Sstevel@tonic-gate*)
510Sstevel@tonic-gate	echo "Usage: $0 { start | stop }"
520Sstevel@tonic-gate	exit 1
530Sstevel@tonic-gate	;;
540Sstevel@tonic-gateesac
550Sstevel@tonic-gate
567045SokieNWAM_FMRI="svc:/network/physical:nwam"
577045SokieNETSVC_FMRI="svc:/network/service:default"
587045Sokie
593938Sjbeckinterface=$2
600Sstevel@tonic-gate
610Sstevel@tonic-gate# If boot variables are not set, set variables we use
620Sstevel@tonic-gate[ -z "$_INIT_UTS_NODENAME" ] && _INIT_UTS_NODENAME=`/usr/bin/uname -n`
630Sstevel@tonic-gate
640Sstevel@tonic-gate#
657045Sokie# This function removes the instance portion of the passed-in FMRI; for
667045Sokie# example, 'svc:/network/service:default' becomes 'svc:/network/service'.
677045Sokie#
687045Sokieremove_fmri_inst () {
697045Sokie	echo $1 | awk -F: ' { printf "%s:%s", $1, $2 } '
707045Sokie}
717045Sokie
727045Sokie#
737045Sokie# This function returns true if this script was *not* invoked
747045Sokie# by an instance of svc:/network/service.
757045Sokie#
767045Sokiefmri_is_not_netsvc () {
777045Sokie	FMRI_1=`remove_fmri_inst $SMF_FMRI`
787045Sokie	FMRI_2=`remove_fmri_inst $NETSVC_FMRI`
797045Sokie	[ "$FMRI_1" = "$FMRI_2" ] && return 1
807045Sokie	return 0
817045Sokie}
827045Sokie
837045Sokie#
847045Sokie# This function returns true if this script was *not* invoked
857045Sokie# by the nwam instance of the network/physical service.
867045Sokie#
877045Sokiefmri_is_not_nwam () {
887045Sokie	[ "&SMF_FMRI" = "$NWAM_FMRI" ] && return 1
897045Sokie	return 0
907045Sokie}
917045Sokie
927045Sokie#
937045Sokie# This function returns true if the nwam service is not running, false
947045Sokie# if it is.  "running" is defined as "current state is online or next
957045Sokie# state is online".
967045Sokie#
977045Sokienwam_is_not_running() {
987045Sokie	state=`/usr/bin/svcprop -p restarter/state $NWAM_FMRI`
997045Sokie	nstate=`/usr/bin/svcprop -p restarter/next_state $NWAM_FMRI`
1007045Sokie
1017045Sokie	[ "$state" = "online" -o "$nextstate" = "online" ] && return 1
1027045Sokie	return 0
1037045Sokie}
1047045Sokie
1057045Sokie#
1060Sstevel@tonic-gate# wait_nis
1070Sstevel@tonic-gate# Wait up to 5 seconds for ypbind to obtain a binding.
1080Sstevel@tonic-gate#
1090Sstevel@tonic-gatewait_nis ()
1100Sstevel@tonic-gate{
1110Sstevel@tonic-gate	for i in 1 2 3 4 5; do
1120Sstevel@tonic-gate		server=`/usr/bin/ypwhich 2>/dev/null`
1130Sstevel@tonic-gate		[ $? -eq 0 -a -n "$server" ] && return 0 || sleep 1
1140Sstevel@tonic-gate	done
1150Sstevel@tonic-gate	return 1
1160Sstevel@tonic-gate}
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate#
1190Sstevel@tonic-gate# This function takes two file names and the file mode as input. The two
1200Sstevel@tonic-gate# files are compared for differences (using cmp(1)) and if different, the
1210Sstevel@tonic-gate# second file is over written with the first. A chmod is done with the file
1220Sstevel@tonic-gate# mode passed in. If the files are equal, the first file passed
1230Sstevel@tonic-gate# in (the /tmp file) is deleted.
1240Sstevel@tonic-gate#
1250Sstevel@tonic-gatemv_file ()
1260Sstevel@tonic-gate{
1270Sstevel@tonic-gate	/usr/bin/cmp -s $1 $2
1280Sstevel@tonic-gate	if [ $? -eq 1 ]; then
1290Sstevel@tonic-gate		/usr/bin/mv $1 $2
1300Sstevel@tonic-gate		#
1310Sstevel@tonic-gate		# The umask during boot is configurable, which requires
1320Sstevel@tonic-gate		# explicit setting of file permission modes when we
1330Sstevel@tonic-gate		# create files.
1340Sstevel@tonic-gate		#
1350Sstevel@tonic-gate		/usr/bin/chmod $3 $2
1360Sstevel@tonic-gate	else
1370Sstevel@tonic-gate		/usr/bin/rm $1
1380Sstevel@tonic-gate	fi
1390Sstevel@tonic-gate}
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate#
1427045Sokie# This function takes a DHCP parameter (as defined in /etc/dhcp/inittab)
1437045Sokie# and returns the value for that parameter returned by the DHCP server.
1447045Sokie# If the global 'interface' is defined, it will request the value learned
1457045Sokie# on that interface, else it will request the value learned on the primary
1467045Sokie# interface.
1477045Sokie#
1487045Sokieget_dhcp_var ()
1497045Sokie{
1507045Sokie	if [ -n "$interface" ]; then
1517045Sokie		/sbin/dhcpinfo -i $interface $1
1527045Sokie	else
1537045Sokie		/sbin/dhcpinfo $1
1547045Sokie	fi
1557045Sokie}
1567045Sokie
1577045Sokie#
1587045Sokie# This function returns true if the string "# Added by DHCP$" occurs in
1597045Sokie# the passed-in file, false otherwise.
1607045Sokie#
1617045Sokiedhcp_edits ()
1627045Sokie{
1637045Sokie	/usr/bin/grep '# Added by DHCP$' $1 >/dev/null 2>&1
1647045Sokie	return $?
1657045Sokie}
1667045Sokie
1677045Sokie#
1687045Sokie# update_resolv()
1697045Sokie# Go through /etc/resolv.conf and replace any existing domain or
1707045Sokie# nameserver entries with new ones derived from DHCP.  Note that
1717045Sokie# it is important to preserve order of domain entries vs. search
1727045Sokie# entries; the search entries are reserved for administrator
1737045Sokie# customization and if placed after the domain entry will override
1747045Sokie# it.  See resolv.conf(4).
1757045Sokie#
1767045Sokie# The first arg should be the dns servers string, the second
1777045Sokie# should be the dns domain.
1787045Sokie#
1797045Sokieupdate_resolv ()
1807045Sokie{
1817045Sokie	dnsservers=$1
1827045Sokie	dnsdomain=$2
1837045Sokie
1847045Sokie	if [ ! -f /etc/resolv.conf ]; then
1857045Sokie		/usr/bin/touch /etc/resolv.conf
1867045Sokie	fi
1877045Sokie	export dnsservers dnsdomain
1887045Sokie	/usr/bin/nawk </etc/resolv.conf >/tmp/resolv.conf.$$ '
1897045Sokie		function writedomain() {
1907045Sokie			if (updated == 0) {
1917045Sokie			    	# Use only first domain, not a search list
1927045Sokie			    	split(ENVIRON["dnsdomain"], d)
1937045Sokie				if(length(d[1]) != 0)
1947045Sokie					printf("domain %s\n", d[1])
1957045Sokie			}
1967045Sokie			++updated
1977045Sokie		}
1987045Sokie		$1 == "domain" { writedomain(); next }
1997045Sokie		$1 != "nameserver" { print $0 }
2007045Sokie		END {
2017045Sokie			writedomain()
2027045Sokie			n = split(ENVIRON["dnsservers"], s)
2037045Sokie			for (i = 1; i <= n; ++i)
2047045Sokie				printf("nameserver %s\n", s[i])
2057045Sokie		}'
2067045Sokie	unset dnsservers dnsdomain
2077045Sokie	mv_file /tmp/resolv.conf.$$ /etc/resolv.conf 644
2087045Sokie}
2097045Sokie
2107045Sokie#
2110Sstevel@tonic-gate# update_nss
2120Sstevel@tonic-gate# This routine takes as a parameter, the name of the respective policy
2130Sstevel@tonic-gate# to change in the nsswitch.conf (hosts or ipnodes) to update with dns.
2140Sstevel@tonic-gate#
2150Sstevel@tonic-gateupdate_nss ()
2160Sstevel@tonic-gate{
2170Sstevel@tonic-gate	policy=$1;
2180Sstevel@tonic-gate	# Add dns to the nsswitch file, if it isn't already there.
2190Sstevel@tonic-gate	/usr/bin/awk ' $1 ~ /^'${policy}':/ {
2200Sstevel@tonic-gate		n = split($0, a);
2210Sstevel@tonic-gate		newl = a[1];
2220Sstevel@tonic-gate		if ($0 !~ /dns/) {
2230Sstevel@tonic-gate			printf("#%s # Commented out by DHCP\n", $0);
2240Sstevel@tonic-gate			updated = 0;
2250Sstevel@tonic-gate			for (i = 2; i <= n; i++) {
2260Sstevel@tonic-gate				if (updated == 0 && index(a[i], "[") == 1) {
2270Sstevel@tonic-gate					newl = newl" dns";
2280Sstevel@tonic-gate					updated++;
2290Sstevel@tonic-gate				}
2300Sstevel@tonic-gate				newl = newl" "a[i];
2310Sstevel@tonic-gate			}
2320Sstevel@tonic-gate			if (updated == 0) {
2330Sstevel@tonic-gate				newl = newl" dns";
2340Sstevel@tonic-gate				updated++;
2350Sstevel@tonic-gate			}
2360Sstevel@tonic-gate			if (updated != 0)
2370Sstevel@tonic-gate				newl = newl" # Added by DHCP";
2380Sstevel@tonic-gate			else
2390Sstevel@tonic-gate				newl = $0;
2400Sstevel@tonic-gate			printf("%s\n", newl);
2410Sstevel@tonic-gate		} else
2420Sstevel@tonic-gate			printf("%s\n", $0);
2430Sstevel@tonic-gate	} $1 !~ /^'${policy}':/ { printf("%s\n", $0); }' /etc/nsswitch.conf \
2440Sstevel@tonic-gate	    >/tmp/nsswitch.conf.$$
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate	mv_file /tmp/nsswitch.conf.$$ /etc/nsswitch.conf 644
2470Sstevel@tonic-gate}
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate#
2507045Sokie# Remove any lines with the "# Added by DHCP" tag from /etc/nsswitch.conf;
2517045Sokie# also uncomment hosts and ipnodes entries which were previously commented
2527045Sokie# out by this script.
2530Sstevel@tonic-gate#
2547045Sokiecleanup_nss ()
2557045Sokie{
2560Sstevel@tonic-gate	/usr/bin/sed \
2570Sstevel@tonic-gate	    -e '/# Added by DHCP$/d' \
2580Sstevel@tonic-gate	    -e 's/^\(#hosts:\)\(.*[^#]\)\(#.*\)$/hosts: \2/' \
2590Sstevel@tonic-gate	    -e 's/^\(#ipnodes:\)\(.*[^#]\)\(#.*\)$/ipnodes: \2/' \
2600Sstevel@tonic-gate	    /etc/nsswitch.conf >/tmp/nsswitch.conf.$$
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate	mv_file /tmp/nsswitch.conf.$$ /etc/nsswitch.conf 644
2637045Sokie}
2640Sstevel@tonic-gate
2657045Sokie#
2667045Sokie# Remove any lines with the "# Added by DHCP" tag from /etc/inet/hosts.
2677045Sokie#
2687045Sokiecleanup_hosts ()
2697045Sokie{
2703938Sjbeck	/usr/bin/nawk '{
2713938Sjbeck		if (index($0, "# Added by DHCP") == 0 ||
2723938Sjbeck		    $1 == "127.0.0.1" || $1 == "::1") {
2733938Sjbeck			print $0
2743938Sjbeck		}
2753938Sjbeck	}' /etc/inet/hosts > /tmp/hosts.$$
2763938Sjbeck	mv_file /tmp/hosts.$$ /etc/inet/hosts 444
2777045Sokie}
2787045Sokie
2797045Sokie#
2807045Sokie# We now need to reset the netmask and broadcast address for our network
2817045Sokie# interfaces.  Since this may result in a name service lookup, we want to
2827045Sokie# now wait for NIS to come up if we previously started it.
2837045Sokie#
2847045Sokie# Only do this in the non-nwam case.
2857045Sokie#
2867045Sokieif fmri_is_not_nwam; then
2877045Sokie	domain=`/usr/bin/domainname 2>/dev/null`
2887045Sokie
2897045Sokie	[ -z "$domain" ] || [ ! -d /var/yp/binding/$domain ] || wait_nis || \
2907045Sokie    		echo "WARNING: Timed out waiting for NIS to come up" >& 2
2917045Sokie
2927045Sokie	#
2937045Sokie	# Re-set the netmask and broadcast addr for all IP interfaces.  This
2947045Sokie	# ifconfig is run here, after waiting for name services, so that
2957045Sokie	# "netmask +" will find the netmask if it lives in a NIS map. The 'D'
2967045Sokie	# in -auD tells ifconfig NOT to mess with the interface if it is
2977045Sokie	# under DHCP control
2987045Sokie	#
2997045Sokie	/usr/sbin/ifconfig -auD4 netmask + broadcast +
3003938Sjbeckfi
3010Sstevel@tonic-gate
3027045Sokie# Uncomment these lines to print complete network interface configuration
3037045Sokie# echo "network interface configuration:"
3047045Sokie# /usr/sbin/ifconfig -a
3057045Sokie
3067045Sokie#
3077045Sokie# If our network configuration strategy is DHCP, check for DNS
3087045Sokie# configuration parameters obtained from the DHCP server.
3097045Sokie#
3107045Sokie# If NWAM is enabled, it will invoke this script to do this configuration
3117045Sokie# whenever a DHCP lease is obtained; in that case, this configuration
3127045Sokie# should *not* happen when svc:network/service is starting, as it will
3137045Sokie# interfere with the configuration performed by NWAM.
3147045Sokie#
3157045Sokieif nwam_is_not_running || fmri_is_not_netsvc; then
3167045Sokie
3177045Sokie	smf_netstrategy
3187045Sokie
3197045Sokie	if [ "$_INIT_NET_STRATEGY" = "dhcp" ]; then
3207045Sokie		dnsservers=`get_dhcp_var DNSserv`
3217045Sokie		dnsdomain=`get_dhcp_var DNSdmain`
3227045Sokie	else
3237045Sokie		dnsservers=""
3247045Sokie		dnsdomain=""
3257045Sokie	fi
3267045Sokie
3277045Sokie	if [ -n "$dnsservers" ]; then
3287045Sokie		#
3297045Sokie		# add settings retrieved from dhcp server to /etc/resolv.conf
3307045Sokie		#
3317045Sokie		update_resolv "$dnsservers" "$dnsdomain"
3327045Sokie
3337045Sokie		#
3347045Sokie		# Add dns to the nsswitch file, if it isn't already there.
3357045Sokie		#
3367045Sokie		update_nss hosts
3377045Sokie		update_nss ipnodes
3387045Sokie
3397045Sokie	elif dhcp_edits /etc/nsswitch.conf; then
3407045Sokie		# If we added DNS to the hosts and ipnodes
3417045Sokie		# policy in the nsswitch, remove it.
3427045Sokie		cleanup_nss
3437045Sokie	fi
3447045Sokiefi
3457045Sokie
3467045Sokieif dhcp_edits /etc/inet/hosts; then
3477045Sokie	# Clean up any old DHCP-added entries
3487045Sokie	# (except loopback) in the hosts file.
3497045Sokie	cleanup_hosts
3507045Sokiefi
3517045Sokie
3527045Sokie#
3537045Sokie# If we were invoked by NWAM, can exit now (skipping the ipqos config)
3547045Sokie#
3557045Sokieif [ -z "$SMF_FMRI" ] || [ "$SMF_FMRI" = "$NWAM_FMRI" ]; then
3564121Samaguire        exit 0
3574121Samaguirefi
3584121Samaguire
3594121Samaguire#
3604121Samaguire# Load the IPQoS configuration.
3614121Samaguire# This is backgrounded so that any remote hostname lookups it performs
3624121Samaguire# don't unduely delay startup. Any messages go via syslog.
3634121Samaguire#
3644121Samaguire
3654121Samaguireif [ -f /usr/sbin/ipqosconf -a -f /etc/inet/ipqosinit.conf ]; then
3664121Samaguire        /usr/sbin/ipqosconf -s -a /etc/inet/ipqosinit.conf &
3674121Samaguirefi
368