changeset 12909:d4754c89220d

PSARC/2010/111 exclusive IP for s10c 6858460 support exclusive stack for solaris10-branded zone 6905944 netstat -rn output on solaris10 branded zones differ from native solaris10
author Baban Kenkre <Baban.Kenkre@Sun.COM>
date Fri, 23 Jul 2010 16:52:46 -0400
parents 7f69e106d260
children 74125a322c70
files usr/src/cmd/cmd-inet/lib/ipmgmtd/net-ipmgmt usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c usr/src/lib/brand/solaris10/cmd/Makefile usr/src/lib/brand/solaris10/cmd/s10_net_physical.sh usr/src/lib/brand/solaris10/s10_support/s10_support.c usr/src/lib/brand/solaris10/zone/p2v.ksh usr/src/lib/brand/solaris10/zone/s10_boot.ksh usr/src/pkg/manifests/system-zones-brand-s10.mf usr/src/uts/common/inet/ip.h usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/mib2.h usr/src/uts/common/inet/snmpcom.c usr/src/uts/common/inet/snmpcom.h usr/src/uts/common/inet/tcp.h usr/src/uts/common/inet/tcp/tcp_stats.c usr/src/uts/common/inet/udp/udp_stats.c usr/src/uts/common/inet/udp_impl.h
diffstat 17 files changed, 762 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/net-ipmgmt	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/net-ipmgmt	Fri Jul 23 16:52:46 2010 -0400
@@ -20,8 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 #
 # This daemon stores address object to logical interface number mappings
 # (among other things) and reads/writes from/to ipmgmtd data store.
@@ -41,7 +40,10 @@
 # service, the service will go into maintenance mode and so will all it's
 # dependents.
 #
-if smf_is_nonglobalzone; then
+# In S10C zone (where this script is also used) smf_isnonglobalzone
+# function is unavailable in smf_include.sh
+#
+if [ `/sbin/zonename` != global ]; then
 	if [ `/sbin/zonename -t` = shared ]; then
 		(while true ; do sleep 3600 ; done) & 
 		exit $SMF_EXIT_OK
@@ -49,7 +51,10 @@
 fi
 
 # Apply any persistent protocol (IP/TCP/SCTP/UDP/ICMP) properties
-/sbin/ipadm init-prop
+# ipadm doesn't exist and init-prop isn't required inside S10C
+if [ -f /sbin/ipadm ]; then
+	/sbin/ipadm init-prop
+fi
 
 #
 # We must be now in a global zone or non-global zone with exclusive-IP stack.
--- a/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c	Fri Jul 23 16:52:46 2010 -0400
@@ -744,7 +744,7 @@
 	req = (struct opthdr *)&tor[1];
 	req->level = EXPER_IP_AND_ALL_IRES;
 	req->name  = 0;
-	req->len   = 0;
+	req->len   = 1;
 
 	ctlbuf.buf = (char *)buf;
 	ctlbuf.len = tor->OPT_length + tor->OPT_offset;
--- a/usr/src/lib/brand/solaris10/cmd/Makefile	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/lib/brand/solaris10/cmd/Makefile	Fri Jul 23 16:52:46 2010 -0400
@@ -22,7 +22,8 @@
 # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
-PROGS =		s10_native s10_isaexec_wrapper s10_python_wrapper
+PROGS =		s10_native s10_isaexec_wrapper s10_python_wrapper \
+		s10_net_physical
 
 include $(SRC)/cmd/Makefile.cmd
 include ../Makefile.s10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/brand/solaris10/cmd/s10_net_physical.sh	Fri Jul 23 16:52:46 2010 -0400
@@ -0,0 +1,450 @@
+#!/sbin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
+# All rights reserved.
+#
+# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
+# The copyright notice above does not evidence any
+# actual or intended publication of such source code.
+#
+
+. /lib/svc/share/smf_include.sh
+. /lib/svc/share/net_include.sh
+
+#
+# This file replaces the Solaris 10 net-physical script in S10C at
+# boot time. Any S10C specific changes to net-physical script needs
+# to be made in this file. 
+#
+
+#
+# In a shared-IP zone we need this service to be up, but all of the work
+# it tries to do is irrelevant (and will actually lead to the service
+# failing if we try to do it), so just bail out.
+# In exclusive-IP zones we proceed.
+#
+if [ `/sbin/zonename -t` = shared ]; then
+	exit 0
+fi
+
+# Print warnings to console
+warn_failed_ifs() {
+	echo "Failed to $1 interface(s): $2" >/dev/msglog
+}
+
+#
+# Cause ifconfig to not automatically start in.mpathd when IPMP groups are
+# configured.  This is not strictly necessary but makes it so that in.mpathd
+# will always be started explicitly from /etc/init.d/inetinit, when we're
+# sure that /usr is mounted.
+#
+SUNW_NO_MPATHD=; export SUNW_NO_MPATHD
+
+smf_netstrategy
+
+#
+# If the system was net booted by DHCP, hand DHCP management off to the
+# DHCP agent (ifconfig communicates to the DHCP agent through the
+# loopback interface).
+#
+if [ -n "$_INIT_NET_IF" -a "$_INIT_NET_STRATEGY" = "dhcp" ]; then
+	/sbin/dhcpagent -a
+fi
+
+#
+# For IPv4 interfaces that were configured by the kernel and not
+# configured by DHCP, reset the netmask using the local "/etc/netmasks"
+# file if one exists, and then reset the broadcast address based on
+# the netmask.
+#
+/sbin/ifconfig -auD4 netmask + broadcast +
+
+#
+# All the IPv4 and IPv6 interfaces are plumbed before doing any
+# interface configuration.  This prevents errors from plumb failures
+# getting mixed in with the configured interface lists that the script
+# outputs.
+#
+# Moreover in S10C, we process IPMP interfaces before non-IPMP
+# interfaces to avoid accidental implicit IPMP group creation.
+# Therefore we keep track of IPMP and non-IPMP interfaces in two
+# different lists i.e. ipmp[6]_list vs inet[6]_list.
+
+#
+# Get the list of IPv4 interfaces to configure by breaking
+# /etc/hostname.* into separate args by using "." as a shell separator
+# character.
+#
+interface_names="`echo /etc/hostname.*[0-9] 2>/dev/null`"
+if [ "$interface_names" != "/etc/hostname.*[0-9]" ]; then
+	ORIGIFS="$IFS"
+	IFS="$IFS."
+	set -- $interface_names
+	IFS="$ORIGIFS"
+	while [ $# -ge 2 ]; do
+		shift
+		if [ "$1" = "xx0" ]; then
+			#
+			# For some unknown historical reason the xx0
+			# ifname is ignored.
+			#
+			shift
+			continue
+		fi
+		if [ $# -gt 1 -a "$2" != "/etc/hostname" ]; then
+			while [ $# -gt 1 -a "$1" != "/etc/hostname" ]; do
+				shift
+			done
+		else
+			read one rest < /etc/hostname.$1
+			if [ "$one" = ipmp ]; then
+				ipmp_list="$ipmp_list $1"
+			else
+				inet_list="$inet_list $1"
+			fi
+			shift
+		fi
+	done
+fi
+
+#
+# Get the list of IPv6 interfaces to configure by breaking
+# /etc/hostname6.* into separate args by using "." as a shell separator
+# character.
+#
+interface_names="`echo /etc/hostname6.*[0-9] 2>/dev/null`"
+if [ "$interface_names" != "/etc/hostname6.*[0-9]" ]; then
+	ORIGIFS="$IFS"
+	IFS="$IFS."
+	set -- $interface_names
+	IFS="$ORIGIFS"
+	while [ $# -ge 2 ]; do
+		shift
+		if [ $# -gt 1 -a "$2" != "/etc/hostname6" ]; then
+			while [ $# -gt 1 -a "$1" != "/etc/hostname6" ]; do
+				shift
+			done
+		else
+			read one rest < /etc/hostname6.$1
+			if [ "$one" = ipmp ]; then
+				ipmp6_list="$ipmp6_list $1"
+			else
+				inet6_list="$inet6_list $1"
+			fi
+			shift
+		fi
+	done
+fi
+
+#
+# Create all of the IPv4 IPMP interfaces.
+#
+if [ -n "$ipmp_list" ]; then
+	set -- $ipmp_list
+	while [ $# -gt 0 ]; do
+		if /sbin/ifconfig $1 ipmp; then
+			ipmp_created="$ipmp_created $1"
+		else
+			ipmp_failed="$ipmp_failed $1"
+		fi
+		shift
+	done
+	[ -n "$ipmp_failed" ] && warn_failed_ifs "create IPv4 IPMP" \
+	    "$ipmp_failed"
+fi
+
+#
+# Step through the IPv4 interface list and try to plumb every interface.
+# Generate list of plumbed and failed IPv4 interfaces.
+#
+if [ -n "$inet_list" ]; then
+	set -- $inet_list
+	while [ $# -gt 0 ]; do
+		/sbin/ifconfig $1 plumb
+		if /sbin/ifconfig $1 inet >/dev/null 2>&1; then
+			inet_plumbed="$inet_plumbed $1"
+		else
+			inet_failed="$inet_failed $1"
+		fi
+		shift
+	done
+	[ -n "$inet_failed" ] && warn_failed_ifs "plumb IPv4" $inet_failed
+fi
+
+#
+# Step through the IPv6 interface list and plumb every interface.
+# Generate list of plumbed and failed IPv6 interfaces.  Each plumbed
+# interface will be brought up later, after processing any contents of
+# the /etc/hostname6.* file.
+#
+if [ -n "$inet6_list" ]; then
+	set -- $inet6_list
+	while [ $# -gt 0 ]; do
+		/sbin/ifconfig $1 inet6 plumb
+		if /sbin/ifconfig $1 inet6 >/dev/null 2>&1; then
+			inet6_plumbed="$inet6_plumbed $1"
+		else
+			inet6_failed="$inet6_failed $1"
+		fi
+		shift
+	done
+	[ -n "$inet6_failed" ] && warn_failed_ifs "plumb IPv6" $inet6_failed
+fi
+
+#
+# Create all of the IPv6 IPMP interfaces.
+#
+if [ -n "$ipmp6_list" ]; then
+	set -- $ipmp6_list
+	while [ $# -gt 0 ]; do
+		if /sbin/ifconfig $1 inet6 ipmp; then
+			ipmp6_created="$ipmp6_created $1"
+		else
+			ipmp6_failed="$ipmp6_failed $1"
+		fi
+		shift
+	done
+	[ -n "$ipmp6_failed" ] && warn_failed_ifs "create IPv6 IPMP" \
+	    "$ipmp6_failed"
+fi
+
+#
+# Process IPMP interfaces before non-IPMP interfaces
+# to avoid accidental implicit IPMP group creation.
+#
+if [ -n "$ipmp_created" ]; then
+	i4s_fail=
+	echo "configuring IPv4 IPMP interfaces:\c"
+	set -- $ipmp_created
+	while [ $# -gt 0 ]; do
+		inet_process_hostname /sbin/ifconfig $1 inet \
+		    </etc/hostname.$1 >/dev/null
+		[ $? != 0 ] && i4s_fail="$i4s_fail $1"
+		echo " $1\c"
+		shift
+	done
+	echo "."
+	[ -n "$i4s_fail" ] && warn_failed_ifs "configure IPv4 IPMP" \
+	    $i4s_fail
+fi
+	
+if [ -n "$ipmp6_created" ]; then
+	i6_fail=
+	echo "configuring IPv6 IPMP interfaces:\c"
+	set -- $ipmp6_created
+	while [ $# -gt 0 ]; do
+		inet6_process_hostname /sbin/ifconfig $1 inet6 \
+		    </etc/hostname6.$1 >/dev/null && 
+		    /sbin/ifconfig $1 inet6 up
+		[ $? != 0 ] && i6_fail="$i6_fail $1"
+		echo " $1\c"
+		shift
+	done
+	echo "."
+	[ -n "$i6_fail" ] && warn_failed_ifs "configure IPv6 IPMP" \
+	    $i6_fail
+fi
+
+#
+# Process the /etc/hostname.* files of plumbed IPv4 interfaces.  If an
+# /etc/hostname file is not present or is empty, the ifconfig auto-dhcp
+# / auto-revarp command will attempt to set the address, later.
+#
+# If /etc/hostname.lo0 exists the loop below will do additional
+# configuration of lo0.
+#
+if [ -n "$inet_plumbed" ]; then
+	i4s_fail=
+	echo "configuring IPv4 interfaces:\c"
+	set -- $inet_plumbed
+	while [ $# -gt 0 ]; do
+		l3protect=`/sbin/ifconfig $1|grep -c L3PROTECT`
+		if [ $l3protect != 0 ]; then
+			echo "Ignoring /etc/hostname.$1" > /dev/msglog
+		else
+			inet_process_hostname /sbin/ifconfig $1 inet \
+			    </etc/hostname.$1 >/dev/null
+			[ $? != 0 ] && i4s_fail="$i4s_fail $1"
+			echo " $1\c"
+		fi
+		shift
+	done
+	echo "."
+	[ -n "$i4s_fail" ] && warn_failed_ifs "configure IPv4" $i4s_fail
+fi
+
+#
+# Process the /etc/hostname6.* files of plumbed IPv6 interfaces.  After
+# processing the hostname6 file, bring the interface up.  If
+# /etc/hostname6.lo0 exists the loop below will do additional
+# configuration of lo0.
+#
+if [ -n "$inet6_plumbed" ]; then
+	i6_fail=
+	echo "configuring IPv6 interfaces:\c"
+	set -- $inet6_plumbed
+	while [ $# -gt 0 ]; do
+		l3protect=`/sbin/ifconfig $1|grep -c L3PROTECT`
+		if [ $l3protect != 0 ]; then
+			echo "Ignoring /etc/hostname6.$1" > /dev/msglog
+		else
+			inet6_process_hostname /sbin/ifconfig $1 inet6 \
+			    </etc/hostname6.$1 >/dev/null && 
+			    /sbin/ifconfig $1 inet6 up
+			[ $? != 0 ] && i6_fail="$i6_fail $1"
+			echo " $1\c"
+		fi
+		shift
+	done
+	echo "."
+	[ -n "$i6_fail" ] && warn_failed_ifs "configure IPv6" $i6_fail
+fi
+
+# Run DHCP if requested. Skip boot-configured interface.
+interface_names="`echo /etc/dhcp.*[0-9] 2>/dev/null`"
+if [ "$interface_names" != '/etc/dhcp.*[0-9]' ]; then
+	#
+	# First find the primary interface. Default to the first
+	# interface if not specified. First primary interface found
+	# "wins". Use care not to "reconfigure" a net-booted interface
+	# configured using DHCP. Run through the list of interfaces
+	# again, this time trying DHCP.
+	#
+	i4d_fail=
+	firstif=
+	primary=
+	ORIGIFS="$IFS"
+	IFS="${IFS}."
+	set -- $interface_names
+
+	while [ $# -ge 2 ]; do
+		shift
+		[ -z "$firstif" ] && firstif=$1
+
+		for i in `shcat /etc/dhcp\.$1`; do
+			if [ "$i" = primary ]; then
+				primary=$1
+				break
+			fi
+		done
+
+		[ -n "$primary" ] && break
+		shift
+	done
+
+	[ -z "$primary" ] && primary="$firstif"
+	cmdline=`shcat /etc/dhcp\.${primary}`
+
+	if [ "$_INIT_NET_IF" != "$primary" ]; then
+		echo "starting DHCP on primary interface $primary"
+		/sbin/ifconfig $primary auto-dhcp primary $cmdline
+		# Exit code 4 means ifconfig timed out waiting for dhcpagent
+		[ $? != 0 ]  && [ $? != 4 ] && i4d_fail="$i4d_fail $primary"
+	fi
+
+	set -- $interface_names
+
+	while [ $# -ge 2 ]; do
+		shift
+		cmdline=`shcat /etc/dhcp\.$1`
+		if [ "$1" != "$primary" -a \
+			"$1" != "$_INIT_NET_IF"  ]; then
+			echo "starting DHCP on interface $1"
+			/sbin/ifconfig $1 dhcp start wait 0 $cmdline
+			# Exit code can't be timeout when wait is 0
+			[ $? != 0 ] && i4d_fail="$i4d_fail $1"
+		fi
+		shift
+	done
+	IFS="$ORIGIFS"
+	unset ORIGIFS
+	[ -n "$i4d_fail" ] && warn_failed_ifs "configure IPv4 DHCP" $i4d_fail
+fi
+
+# 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 /etc/nodename
+hostname="`shcat /etc/nodename 2>/dev/null`"
+if [ "$_INIT_NET_STRATEGY" = "rarp" -o -z "$hostname" ]; then
+        /sbin/ifconfig -adD4 auto-revarp netmask + broadcast + up
+fi
+
+#
+# Process IPv4 and IPv6 interfaces that failed to plumb.  Find an
+# alternative interface to host the addresses.
+#
+[ -n "$inet_failed" ] && move_addresses inet
+
+[ -n "$inet6_failed" ] && move_addresses inet6
+
+#
+# If the /etc/defaultrouter file exists, process it now so that the next
+# stage of booting will have access to NFS.
+#
+if [ -f /etc/defaultrouter ]; then
+	while read router rubbish; do
+		case "$router" in
+			'#'* | '') ;;	#  Ignore comments, empty lines
+			*)	/sbin/route -n add default -gateway $router ;;
+		esac
+	done </etc/defaultrouter
+fi
+
+#
+# We tell smf this service is online if any of the following is true:
+# - no interfaces were configured for plumbing and no DHCP failures
+# - there are any DHCP interfaces started
+# - any non-loopback, non-DHCP IPv4 interfaces are up and have a non-zero
+#   address
+# - any non-loopback IPv6 interfaces are up
+#
+# If we weren't asked to configure any interfaces, exit
+if [ -z "$inet_list" ] && [ -z "$inet6_list" ]; then
+	# Config error if DHCP was attempted without plumbed interfaces
+	[ -n "$i4d_fail" ] && exit $SMF_EXIT_ERR_CONFIG
+	exit $SMF_EXIT_OK
+fi
+
+# Any DHCP interfaces?
+[ -n "`/sbin/ifconfig -a4 dhcp status 2>/dev/null`" ] && exit $SMF_EXIT_OK
+
+# Any non-loopback, non-DHCP IPv4 interfaces with usable addresses up?
+if [ -n "`/sbin/ifconfig -a4uD`" ]; then
+    	/sbin/ifconfig -a4uD | while read intf addr rest; do
+		[ $intf = inet ] && [ $addr != 127.0.0.1 ] &&
+		[ $addr != 0.0.0.0 ] && exit 0
+	done && exit $SMF_EXIT_OK
+fi
+
+# Any non-loopback IPv6 interfaces up?
+if [ -n "`/sbin/ifconfig -au6`" ]; then
+	/sbin/ifconfig -au6 | while read intf addr rest; do
+		[ $intf = inet6 ] && [ $addr != ::1/128 ] && exit 0
+	done && exit $SMF_EXIT_OK
+fi
+
+# This service was supposed to configure something yet didn't.  Exit
+# with config error.
+exit $SMF_EXIT_ERR_CONFIG
--- a/usr/src/lib/brand/solaris10/s10_support/s10_support.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/lib/brand/solaris10/s10_support/s10_support.c	Fri Jul 23 16:52:46 2010 -0400
@@ -100,7 +100,6 @@
 {
 	zone_dochandle_t	handle;
 	struct zone_devtab	devtab;
-	zone_iptype_t		iptype;
 
 	if ((handle = zonecfg_init_handle()) == NULL)
 		s10_err(gettext("internal libzonecfg.so.1 error"), 0);
@@ -134,17 +133,6 @@
 	}
 	(void) zonecfg_enddevent(handle);
 
-	/*
-	 * Check to see whether the zone has any experimental features
-	 * configured.
-	 */
-	if (zonecfg_get_iptype(handle, &iptype) == Z_OK &&
-	    iptype == ZS_EXCLUSIVE && !override) {
-		zonecfg_fini_handle(handle);
-		s10_err(gettext("solaris10 zones do not currently support "
-		    "exclusive ip-type stacks"));
-	}
-
 	zonecfg_fini_handle(handle);
 	return (0);
 }
--- a/usr/src/lib/brand/solaris10/zone/p2v.ksh	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/lib/brand/solaris10/zone/p2v.ksh	Fri Jul 23 16:52:46 2010 -0400
@@ -333,6 +333,13 @@
 	[[ -n $LOGFILE ]] && cat $insttmpfile >&2
 
 	#
+	# Import ip-interface-management service in S10C, network
+	# loopback service requires ipmgmtd in exclusive stack zones.
+	#
+	/usr/sbin/zlogin -S $ZONENAME /usr/sbin/svccfg import \
+	    $ZONEROOT/var/svc/manifest/network/network-ipmgmt.xml
+
+	#
 	# Fix network services if shared stack.
 	#
 	if [[ "$STACK_TYPE" == "shared" ]]; then
--- a/usr/src/lib/brand/solaris10/zone/s10_boot.ksh	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/lib/brand/solaris10/zone/s10_boot.ksh	Fri Jul 23 16:52:46 2010 -0400
@@ -95,11 +95,23 @@
 	fi
 }
 
+#
+# Create a new wrapper script that invokes s10_isaexec_wrapper in the
+# brand (for a non-existing s10c file) pointing to the native brand file.
+#
+# Parameters:
+#	$1	The full path of the wrapper file to create
+#	$2	The access mode of the replacement file in hex (e.g., 0555)
+#	$3	The name of the replacement file's owner (e.g., root:bin)
+#
 wrap_with_native() {
 
 	[ ! -f $1 ] && printf "$w_missing" "$1"
 
-	safe_wrap $ZONEROOT/$1 $BRANDDIR/s10_isaexec_wrapper $2 $3
+	path_dname=$ZONEROOT/`dirname $1`
+	if [ ! -h $path_dname -a -d $path_dname -a ! -f $ZONEROOT/$1 ]; then
+		safe_wrap $ZONEROOT/$1 $BRANDDIR/s10_isaexec_wrapper $2 $3
+	fi
 }
 
 #
@@ -143,17 +155,42 @@
 #
 # Validate that the zone filesystem looks like we expect it to.
 #
+safe_dir /lib
+safe_dir /lib/svc
+safe_dir /lib/svc/method
+safe_dir /lib/svc/share
 safe_dir /usr
+safe_dir /usr/bin
 safe_dir /usr/lib
 safe_dir /usr/lib/autofs
 safe_dir /usr/lib/fs
 safe_dir /usr/lib/fs/autofs
 safe_dir /usr/lib/fs/ufs
 safe_dir /usr/lib/fs/zfs
+safe_dir /usr/lib/inet
 safe_dir /usr/lib/zfs
-safe_dir /usr/bin
 safe_dir /usr/sbin
+if [ -n "$ARCH32" ]; then
+	safe_dir /usr/lib/ipf/$ARCH32
+	safe_dir /usr/sbin/$ARCH32
+fi
+if [ -n "$ARCH64" ]; then
+	safe_dir /usr/lib/ipf/$ARCH64
+	safe_dir /usr/sbin/$ARCH64
+fi
 safe_dir /sbin
+safe_dir /var
+safe_dir /var/svc
+safe_dir /var/svc/manifest
+safe_dir /var/svc/manifest/network
+
+#
+# Some of the native networking daemons such as in.mpathd are
+# expected under /lib/inet
+#
+mkdir -m 0755 -p $ZONEROOT/lib/inet
+chown root:bin $ZONEROOT/lib/inet
+safe_dir /lib/inet
 
 #
 # STEP TWO
@@ -164,7 +201,75 @@
 #
 # Replace various network-related programs with native wrappers.
 #
+replace_with_native /sbin/dhcpagent 0555 root:bin
+replace_with_native /sbin/dhcpinfo 0555 root:bin
 replace_with_native /sbin/ifconfig 0555 root:bin
+replace_with_native /usr/bin/netstat 0555 root:bin
+replace_with_native /usr/lib/inet/in.ndpd 0555 root:bin
+replace_with_native /usr/sbin/in.routed 0555 root:bin
+replace_with_native /usr/sbin/ndd 0555 root:bin
+replace_with_native /usr/sbin/snoop 0555 root:bin
+replace_with_native /usr/sbin/if_mpadm 0555 root:bin
+
+#
+# Replace IPFilter commands with native wrappers
+#
+if [ -n "$ARCH32" ]; then
+	replace_with_native /usr/lib/ipf/$ARCH32/ipftest 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ipf 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ipfs 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ipfstat 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ipmon 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ipnat 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH32/ippool 0555 root:bin
+fi
+if [ -n "$ARCH64" ]; then
+	replace_with_native /usr/lib/ipf/$ARCH64/ipftest 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ipf 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ipfs 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ipfstat 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ipmon 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ipnat 0555 root:bin
+	replace_with_native /usr/sbin/$ARCH64/ippool 0555 root:bin
+fi
+
+#
+# Replace in.mpathd daemon at /usr/lib/inet by native wrapper
+#
+if [ ! -h $ZONEROOT/usr/lib/inet -a -d $ZONEROOT/usr/lib/inet ]; then
+	safe_replace $ZONEROOT/usr/lib/inet/in.mpathd \
+	    /lib/inet/in.mpathd 0555 root:bin remove
+fi
+
+# 
+# Create wrapper at /lib/inet/in.mpathd as well because native ifconfig
+# looks up in.mpathd under /lib/inet.
+#
+wrap_with_native /lib/inet/in.mpathd 0555 root:bin
+
+# Create native wrapper for /sbin/ipmpstat
+wrap_with_native /sbin/ipmpstat 0555 root:bin
+
+#
+# Create ipmgmtd wrapper to native binary in s10 container
+# and copy ipmgmt service manifest and method.
+#
+wrap_with_native /lib/inet/ipmgmtd 0555 root:bin
+safe_copy /lib/svc/manifest/network/network-ipmgmt.xml \
+    $ZONEROOT/var/svc/manifest/network/network-ipmgmt.xml
+safe_copy /lib/svc/method/net-ipmgmt \
+    $ZONEROOT/lib/svc/method/net-ipmgmt
+
+#
+# To handle certain IPMP configurations, we need updated
+# net-physical method script and native net_include.sh
+#
+filename=$ZONEROOT/lib/svc/method/net-physical
+safe_backup $filename $filename.pre_p2v
+safe_copy /usr/lib/brand/solaris10/s10_net_physical $filename
+filename=$ZONEROOT/lib/svc/share/net_include.sh
+safe_backup $filename $filename.pre_p2v
+safe_copy /lib/svc/share/net_include.sh $filename
 
 #
 # PSARC 2009/306 removed the ND_SET/ND_GET ioctl's for modifying
--- a/usr/src/pkg/manifests/system-zones-brand-s10.mf	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/pkg/manifests/system-zones-brand-s10.mf	Fri Jul 23 16:52:46 2010 -0400
@@ -82,6 +82,7 @@
 file path=usr/lib/brand/solaris10/s10_boot mode=0755
 file path=usr/lib/brand/solaris10/s10_isaexec_wrapper mode=0755
 file path=usr/lib/brand/solaris10/s10_native mode=0755
+file path=usr/lib/brand/solaris10/s10_net_physical mode=0755
 file path=usr/lib/brand/solaris10/s10_python_wrapper mode=0755
 file path=usr/lib/brand/solaris10/s10_replacefile mode=0755
 file path=usr/lib/brand/solaris10/s10_support mode=0755
--- a/usr/src/uts/common/inet/ip.h	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/ip.h	Fri Jul 23 16:52:46 2010 -0400
@@ -3442,7 +3442,7 @@
 extern uint8_t	ipoptp_first(ipoptp_t *, ipha_t *);
 extern int	ip_opt_get_user(conn_t *, uchar_t *);
 extern int	ipsec_req_from_conn(conn_t *, ipsec_req_t *, int);
-extern int	ip_snmp_get(queue_t *q, mblk_t *mctl, int level);
+extern int	ip_snmp_get(queue_t *q, mblk_t *mctl, int level, boolean_t);
 extern int	ip_snmp_set(queue_t *q, int, int, uchar_t *, int);
 extern void	ip_process_ioctl(ipsq_t *, queue_t *, mblk_t *, void *);
 extern void	ip_quiesce_conn(conn_t *);
--- a/usr/src/uts/common/inet/ip/ip.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/ip/ip.c	Fri Jul 23 16:52:46 2010 -0400
@@ -671,20 +671,21 @@
 void	ip_rput(queue_t *, mblk_t *);
 static void	ip_rput_dlpi_writer(ipsq_t *dummy_sq, queue_t *q, mblk_t *mp,
 		    void *dummy_arg);
-int		ip_snmp_get(queue_t *, mblk_t *, int);
+int		ip_snmp_get(queue_t *, mblk_t *, int, boolean_t);
 static mblk_t	*ip_snmp_get_mib2_ip(queue_t *, mblk_t *,
-		    mib2_ipIfStatsEntry_t *, ip_stack_t *);
+		    mib2_ipIfStatsEntry_t *, ip_stack_t *, boolean_t);
 static mblk_t	*ip_snmp_get_mib2_ip_traffic_stats(queue_t *, mblk_t *,
-		    ip_stack_t *);
-static mblk_t	*ip_snmp_get_mib2_ip6(queue_t *, mblk_t *, ip_stack_t *);
+		    ip_stack_t *, boolean_t);
+static mblk_t	*ip_snmp_get_mib2_ip6(queue_t *, mblk_t *, ip_stack_t *,
+		    boolean_t);
 static mblk_t	*ip_snmp_get_mib2_icmp(queue_t *, mblk_t *, ip_stack_t *ipst);
 static mblk_t	*ip_snmp_get_mib2_icmp6(queue_t *, mblk_t *, ip_stack_t *ipst);
 static mblk_t	*ip_snmp_get_mib2_igmp(queue_t *, mblk_t *, ip_stack_t *ipst);
 static mblk_t	*ip_snmp_get_mib2_multi(queue_t *, mblk_t *, ip_stack_t *ipst);
 static mblk_t	*ip_snmp_get_mib2_ip_addr(queue_t *, mblk_t *,
-		    ip_stack_t *ipst);
+		    ip_stack_t *ipst, boolean_t);
 static mblk_t	*ip_snmp_get_mib2_ip6_addr(queue_t *, mblk_t *,
-		    ip_stack_t *ipst);
+		    ip_stack_t *ipst, boolean_t);
 static mblk_t	*ip_snmp_get_mib2_ip_group_src(queue_t *, mblk_t *,
 		    ip_stack_t *ipst);
 static mblk_t	*ip_snmp_get_mib2_ip6_group_src(queue_t *, mblk_t *,
@@ -9497,11 +9498,13 @@
  *
  * NOTE: original mpctl is copied for msg's 2..N, since its ctl part is
  * already filled in by the caller.
+ * If legacy_req is true then MIB structures needs to be truncated to their
+ * legacy sizes before being returned.
  * Return value of 0 indicates that no messages were sent and caller
  * should free mpctl.
  */
 int
-ip_snmp_get(queue_t *q, mblk_t *mpctl, int level)
+ip_snmp_get(queue_t *q, mblk_t *mpctl, int level, boolean_t legacy_req)
 {
 	ip_stack_t *ipst;
 	sctp_stack_t *sctps;
@@ -9534,23 +9537,24 @@
 	}
 
 	if (level != MIB2_TCP) {
-		if ((mpctl = udp_snmp_get(q, mpctl)) == NULL) {
+		if ((mpctl = udp_snmp_get(q, mpctl, legacy_req)) == NULL) {
 			return (1);
 		}
 	}
 
 	if (level != MIB2_UDP) {
-		if ((mpctl = tcp_snmp_get(q, mpctl)) == NULL) {
+		if ((mpctl = tcp_snmp_get(q, mpctl, legacy_req)) == NULL) {
 			return (1);
 		}
 	}
 
 	if ((mpctl = ip_snmp_get_mib2_ip_traffic_stats(q, mpctl,
-	    ipst)) == NULL) {
+	    ipst, legacy_req)) == NULL) {
 		return (1);
 	}
 
-	if ((mpctl = ip_snmp_get_mib2_ip6(q, mpctl, ipst)) == NULL) {
+	if ((mpctl = ip_snmp_get_mib2_ip6(q, mpctl, ipst,
+	    legacy_req)) == NULL) {
 		return (1);
 	}
 
@@ -9570,11 +9574,13 @@
 		return (1);
 	}
 
-	if ((mpctl = ip_snmp_get_mib2_ip_addr(q, mpctl, ipst)) == NULL) {
+	if ((mpctl = ip_snmp_get_mib2_ip_addr(q, mpctl, ipst,
+	    legacy_req)) == NULL) {
 		return (1);
 	}
 
-	if ((mpctl = ip_snmp_get_mib2_ip6_addr(q, mpctl, ipst)) == NULL) {
+	if ((mpctl = ip_snmp_get_mib2_ip6_addr(q, mpctl, ipst,
+	    legacy_req)) == NULL) {
 		return (1);
 	}
 
@@ -9623,11 +9629,12 @@
 /* Get global (legacy) IPv4 statistics */
 static mblk_t *
 ip_snmp_get_mib2_ip(queue_t *q, mblk_t *mpctl, mib2_ipIfStatsEntry_t *ipmib,
-    ip_stack_t *ipst)
+    ip_stack_t *ipst, boolean_t legacy_req)
 {
 	mib2_ip_t		old_ip_mib;
 	struct opthdr		*optp;
 	mblk_t			*mp2ctl;
+	mib2_ipAddrEntry_t	mae;
 
 	/*
 	 * make a copy of the original message
@@ -9645,6 +9652,7 @@
 	SET_MIB(old_ip_mib.ipReasmTimeout,
 	    ipst->ips_ip_reassembly_timeout);
 	SET_MIB(old_ip_mib.ipAddrEntrySize,
+	    (legacy_req) ? LEGACY_MIB_SIZE(&mae, mib2_ipAddrEntry_t) :
 	    sizeof (mib2_ipAddrEntry_t));
 	SET_MIB(old_ip_mib.ipRouteEntrySize,
 	    sizeof (mib2_ipRouteEntry_t));
@@ -9718,7 +9726,8 @@
 
 /* Per interface IPv4 statistics */
 static mblk_t *
-ip_snmp_get_mib2_ip_traffic_stats(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
+ip_snmp_get_mib2_ip_traffic_stats(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst,
+    boolean_t legacy_req)
 {
 	struct opthdr		*optp;
 	mblk_t			*mp2ctl;
@@ -9726,6 +9735,7 @@
 	ill_walk_context_t	ctx;
 	mblk_t			*mp_tail = NULL;
 	mib2_ipIfStatsEntry_t	global_ip_mib;
+	mib2_ipAddrEntry_t	mae;
 
 	/*
 	 * Make a copy of the original message
@@ -9756,14 +9766,19 @@
 	SET_MIB(ipst->ips_ip_mib.ipIfStatsGroupSourceEntrySize,
 	    sizeof (ip_grpsrc_t));
 
+	bcopy(&ipst->ips_ip_mib, &global_ip_mib, sizeof (global_ip_mib));
+
+	if (legacy_req) {
+		SET_MIB(global_ip_mib.ipIfStatsAddrEntrySize,
+		    LEGACY_MIB_SIZE(&mae, mib2_ipAddrEntry_t));
+	}
+
 	if (!snmp_append_data2(mpctl->b_cont, &mp_tail,
-	    (char *)&ipst->ips_ip_mib, (int)sizeof (ipst->ips_ip_mib))) {
+	    (char *)&global_ip_mib, (int)sizeof (global_ip_mib))) {
 		ip1dbg(("ip_snmp_get_mib2_ip_traffic_stats: "
 		    "failed to allocate %u bytes\n",
-		    (uint_t)sizeof (ipst->ips_ip_mib)));
-	}
-
-	bcopy(&ipst->ips_ip_mib, &global_ip_mib, sizeof (global_ip_mib));
+		    (uint_t)sizeof (global_ip_mib)));
+	}
 
 	rw_enter(&ipst->ips_ill_g_lock, RW_READER);
 	ill = ILL_START_WALK_V4(&ctx, ipst);
@@ -9795,7 +9810,8 @@
 	if (mp2ctl == NULL)
 		return (NULL);
 
-	return (ip_snmp_get_mib2_ip(q, mp2ctl, &global_ip_mib, ipst));
+	return (ip_snmp_get_mib2_ip(q, mp2ctl, &global_ip_mib, ipst,
+	    legacy_req));
 }
 
 /* Global IPv4 ICMP statistics */
@@ -9879,7 +9895,8 @@
 
 /* IPv4 address information */
 static mblk_t *
-ip_snmp_get_mib2_ip_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
+ip_snmp_get_mib2_ip_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst,
+    boolean_t legacy_req)
 {
 	struct opthdr		*optp;
 	mblk_t			*mp2ctl;
@@ -9888,14 +9905,18 @@
 	ipif_t			*ipif;
 	uint_t			bitval;
 	mib2_ipAddrEntry_t	mae;
+	size_t			mae_size;
 	zoneid_t		zoneid;
-	ill_walk_context_t ctx;
+	ill_walk_context_t	ctx;
 
 	/*
 	 * make a copy of the original message
 	 */
 	mp2ctl = copymsg(mpctl);
 
+	mae_size = (legacy_req) ? LEGACY_MIB_SIZE(&mae, mib2_ipAddrEntry_t) :
+	    sizeof (mib2_ipAddrEntry_t);
+
 	/* ipAddrEntryTable */
 
 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
@@ -9949,10 +9970,9 @@
 			    ill->ill_reachable_retrans_time;
 
 			if (!snmp_append_data2(mpctl->b_cont, &mp_tail,
-			    (char *)&mae, (int)sizeof (mib2_ipAddrEntry_t))) {
+			    (char *)&mae, (int)mae_size)) {
 				ip1dbg(("ip_snmp_get_mib2_ip_addr: failed to "
-				    "allocate %u bytes\n",
-				    (uint_t)sizeof (mib2_ipAddrEntry_t)));
+				    "allocate %u bytes\n", (uint_t)mae_size));
 			}
 		}
 	}
@@ -9967,7 +9987,8 @@
 
 /* IPv6 address information */
 static mblk_t *
-ip_snmp_get_mib2_ip6_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
+ip_snmp_get_mib2_ip6_addr(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst,
+    boolean_t legacy_req)
 {
 	struct opthdr		*optp;
 	mblk_t			*mp2ctl;
@@ -9975,6 +9996,7 @@
 	ill_t			*ill;
 	ipif_t			*ipif;
 	mib2_ipv6AddrEntry_t	mae6;
+	size_t			mae6_size;
 	zoneid_t		zoneid;
 	ill_walk_context_t	ctx;
 
@@ -9983,6 +10005,10 @@
 	 */
 	mp2ctl = copymsg(mpctl);
 
+	mae6_size = (legacy_req) ?
+	    LEGACY_MIB_SIZE(&mae6, mib2_ipv6AddrEntry_t) :
+	    sizeof (mib2_ipv6AddrEntry_t);
+
 	/* ipv6AddrEntryTable */
 
 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
@@ -10054,11 +10080,10 @@
 			mae6.ipv6AddrRetransmitTime =
 			    ill->ill_reachable_retrans_time;
 			if (!snmp_append_data2(mpctl->b_cont, &mp_tail,
-			    (char *)&mae6,
-			    (int)sizeof (mib2_ipv6AddrEntry_t))) {
+			    (char *)&mae6, (int)mae6_size)) {
 				ip1dbg(("ip_snmp_get_mib2_ip6_addr: failed to "
 				    "allocate %u bytes\n",
-				    (uint_t)sizeof (mib2_ipv6AddrEntry_t)));
+				    (uint_t)mae6_size));
 			}
 		}
 	}
@@ -10601,13 +10626,17 @@
  * IPv6 mib: One per ill
  */
 static mblk_t *
-ip_snmp_get_mib2_ip6(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst)
+ip_snmp_get_mib2_ip6(queue_t *q, mblk_t *mpctl, ip_stack_t *ipst,
+    boolean_t legacy_req)
 {
 	struct opthdr		*optp;
 	mblk_t			*mp2ctl;
 	ill_t			*ill;
 	ill_walk_context_t	ctx;
 	mblk_t			*mp_tail = NULL;
+	mib2_ipv6AddrEntry_t	mae6;
+	mib2_ipIfStatsEntry_t	*ise;
+	size_t			ise_size, iae_size;
 
 	/*
 	 * Make a copy of the original message
@@ -10616,6 +10645,15 @@
 
 	/* fixed length IPv6 structure ... */
 
+	if (legacy_req) {
+		ise_size = LEGACY_MIB_SIZE(&ipst->ips_ip6_mib,
+		    mib2_ipIfStatsEntry_t);
+		iae_size = LEGACY_MIB_SIZE(&mae6, mib2_ipv6AddrEntry_t);
+	} else {
+		ise_size = sizeof (mib2_ipIfStatsEntry_t);
+		iae_size = sizeof (mib2_ipv6AddrEntry_t);
+	}
+
 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
 	optp->level = MIB2_IP6;
 	optp->name = 0;
@@ -10657,9 +10695,15 @@
 	    ipIfStatsHCInMcastPkts);
 
 	if (!snmp_append_data2(mpctl->b_cont, &mp_tail,
-	    (char *)&ipst->ips_ip6_mib, (int)sizeof (ipst->ips_ip6_mib))) {
+	    (char *)&ipst->ips_ip6_mib, (int)ise_size)) {
 		ip1dbg(("ip_snmp_get_mib2_ip6: failed to allocate %u bytes\n",
-		    (uint_t)sizeof (ipst->ips_ip6_mib)));
+		    (uint_t)ise_size));
+	} else if (legacy_req) {
+		/* Adjust the EntrySize fields for legacy requests. */
+		ise =
+		    (mib2_ipIfStatsEntry_t *)(mp_tail->b_wptr - (int)ise_size);
+		SET_MIB(ise->ipIfStatsEntrySize, ise_size);
+		SET_MIB(ise->ipIfStatsAddrEntrySize, iae_size);
 	}
 
 	rw_enter(&ipst->ips_ill_g_lock, RW_READER);
@@ -10689,10 +10733,15 @@
 		    ipIfStatsHCInMcastPkts);
 
 		if (!snmp_append_data2(mpctl->b_cont, &mp_tail,
-		    (char *)ill->ill_ip_mib,
-		    (int)sizeof (*ill->ill_ip_mib))) {
+		    (char *)ill->ill_ip_mib, (int)ise_size)) {
 			ip1dbg(("ip_snmp_get_mib2_ip6: failed to allocate "
-			"%u bytes\n", (uint_t)sizeof (*ill->ill_ip_mib)));
+			"%u bytes\n", (uint_t)ise_size));
+		} else if (legacy_req) {
+			/* Adjust the EntrySize fields for legacy requests. */
+			ise = (mib2_ipIfStatsEntry_t *)(mp_tail->b_wptr -
+			    (int)ise_size);
+			SET_MIB(ise->ipIfStatsEntrySize, ise_size);
+			SET_MIB(ise->ipIfStatsAddrEntrySize, iae_size);
 		}
 	}
 	rw_exit(&ipst->ips_ill_g_lock);
--- a/usr/src/uts/common/inet/mib2.h	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/mib2.h	Fri Jul 23 16:52:46 2010 -0400
@@ -18,8 +18,7 @@
  *
  * CDDL HEADER END
  *
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 /* Copyright (c) 1990 Mentat Inc. */
 
@@ -136,6 +135,16 @@
 #define	UPDATE_LOCAL(x, y)	(x) += (y)
 #define	SYNC32_MIB(s, m32, m64)	SET_MIB((s)->m32, (s)->m64 & 0xffffffff)
 
+/*
+ * Each struct that has been extended have a macro (MIB_FIRST_NEW_ELM_type)
+ * that is set to the first new element of the extended struct.
+ * The LEGACY_MIB_SIZE macro can be used to determine the size of MIB
+ * objects that needs to be returned to older applications unaware of
+ * these extensions.
+ */
+#define	MIB_PTRDIFF(s, e)	(caddr_t)e - (caddr_t)s
+#define	LEGACY_MIB_SIZE(s, t)	MIB_PTRDIFF(s, &(s)->MIB_FIRST_NEW_ELM_##t)
+
 #define	OCTET_LENGTH	32	/* Must be at least LIFNAMSIZ */
 typedef struct Octet_s {
 	int	o_length;
@@ -570,6 +579,7 @@
 	Counter		udpNoPorts;
 #define	udpIfStatsNoPorts	udpNoPorts
 } mib2_ipIfStatsEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_ipIfStatsEntry_t	ipIfStatsIPVersion
 
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
@@ -618,6 +628,7 @@
 	}		ipAdEntInfo;
 	uint32_t	ipAdEntRetransmitTime;  /* ipInterfaceRetransmitTime */
 } mib2_ipAddrEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_ipAddrEntry_t	ipAdEntRetransmitTime
 
 /*
  *	ipv6AddrTable OBJECT-TYPE
@@ -667,6 +678,7 @@
 	uint32_t	ipv6AddrReachableTime;	/* InterfaceReachableTime */
 	uint32_t	ipv6AddrRetransmitTime; /* InterfaceRetransmitTime */
 } mib2_ipv6AddrEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_ipv6AddrEntry_t	ipv6AddrReasmMaxSize
 
 /*
  * The IP routing table contains an entry for each route presently known to
@@ -717,6 +729,15 @@
 		Counter		re_obpkt;
 		Counter		re_ibpkt;
 		int		re_flags;
+		/*
+		 * The following two elements (re_in_ill and re_in_src_addr)
+		 * are no longer used but are left here for the benefit of
+		 * old Apps that won't be able to handle the change in the
+		 * size of this struct. These elements will always be
+		 * set to zeroes.
+		 */
+		DeviceName	re_in_ill;	/* Input interface */
+		IpAddress	re_in_src_addr;	/* Input source address */
 	} 		ipRouteInfo;
 } mib2_ipRouteEntry_t;
 
@@ -1293,6 +1314,7 @@
 	/* total # of segments sent				{ tcp 18 } */
 	Counter64	tcpHCOutSegs;
 } mib2_tcp_t;
+#define	MIB_FIRST_NEW_ELM_mib2_tcp_t	tcpHCInSegs
 
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
@@ -1357,6 +1379,8 @@
 	/* system uptime when the connection was created */
 	uint64_t	tcpConnCreationTime;
 } mib2_tcpConnEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_tcpConnEntry_t	tcpConnCreationProcess
+
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
 #endif
@@ -1410,6 +1434,8 @@
 	/* system uptime when the connection was created */
 	uint64_t	tcp6ConnCreationTime;
 } mib2_tcp6ConnEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_tcp6ConnEntry_t	tcp6ConnCreationProcess
+
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
 #endif
@@ -1449,6 +1475,8 @@
 	/* total # of dg's sent					{ udp 9 } */
 	Counter64	udpHCOutDatagrams;
 } mib2_udp_t;
+#define	MIB_FIRST_NEW_ELM_mib2_udp_t	udpHCInDatagrams
+
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
 #endif
@@ -1490,6 +1518,8 @@
 	/* system uptime when the endpoint was created */
 	uint64_t	udpCreationTime;
 } mib2_udpEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_udpEntry_t	udpInstance
+
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
 #endif
@@ -1528,6 +1558,8 @@
 	/* system uptime when the endpoint was created */
 	uint64_t	udp6CreationTime;
 } mib2_udp6Entry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_udp6Entry_t	udp6Instance
+
 #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
 #pragma pack()
 #endif
--- a/usr/src/uts/common/inet/snmpcom.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/snmpcom.c	Fri Jul 23 16:52:46 2010 -0400
@@ -19,13 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 /* Copyright (c) 1990 Mentat Inc. */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * This file contains common code for handling Options Management requests
  * for SNMP/MIB.
@@ -51,6 +48,7 @@
 #include <inet/snmpcom.h>
 
 #include <inet/ip.h>
+#include <sys/brand.h>
 
 #define	DEFAULT_LENGTH	sizeof (long)
 #define	DATA_MBLK_SIZE	1024
@@ -177,6 +175,7 @@
 	sor_t			*sreq;
 	struct T_optmgmt_req	*tor = (struct T_optmgmt_req *)mp->b_rptr;
 	struct T_optmgmt_ack	*toa;
+	boolean_t		legacy_req;
 
 	if (mp->b_cont) {	/* don't deal with multiple mblk's */
 		freemsg(mp->b_cont);
@@ -254,7 +253,18 @@
 		toa->OPT_offset = sizeof (struct T_optmgmt_ack);
 		toa->OPT_length = sizeof (struct opthdr);
 		toa->MGMT_flags = T_SUCCESS;
-		if (!(*getfn)(q, mpctl, req_start->level))
+		/*
+		 * If the current process is running inside a solaris10-
+		 * branded zone and len is 0 then it's a request for
+		 * legacy data.
+		 */
+		if (PROC_IS_BRANDED(curproc) &&
+		    (strcmp(curproc->p_brand->b_name, "solaris10") == 0) &&
+		    (req_start->len == 0))
+			legacy_req = B_TRUE;
+		else
+			legacy_req = B_FALSE;
+		if (!(*getfn)(q, mpctl, req_start->level, legacy_req))
 			freemsg(mpctl);
 		/*
 		 * all data for this module has now been sent upstream.  If
--- a/usr/src/uts/common/inet/snmpcom.h	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/snmpcom.h	Fri Jul 23 16:52:46 2010 -0400
@@ -19,28 +19,29 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 /* Copyright (c) 1990 Mentat Inc. */
 
 #ifndef	_INET_SNMPCOM_H
 #define	_INET_SNMPCOM_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
 #if defined(_KERNEL) && defined(__STDC__)
 
+/* snmpcom_req function prototypes */
+typedef int (*snmp_setf_t)(queue_t *, int, int, uchar_t *, int);
+typedef int (*snmp_getf_t)(queue_t *, mblk_t *, int, boolean_t);
+
 extern int	snmp_append_data(mblk_t *mpdata, char *blob, int len);
 extern int	snmp_append_data2(mblk_t *mpdata, mblk_t **last_mpp,
 		    char *blob, int len);
 
-extern boolean_t	snmpcom_req(queue_t *q, mblk_t *mp, pfi_t setfn,
-    pfi_t getfn, cred_t *cr);
+extern boolean_t	snmpcom_req(queue_t *q, mblk_t *mp,
+    snmp_setf_t setfn, snmp_getf_t getfn, cred_t *cr);
 
 #endif	/* defined(_KERNEL) && defined(__STDC__) */
 
--- a/usr/src/uts/common/inet/tcp.h	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/tcp.h	Fri Jul 23 16:52:46 2010 -0400
@@ -493,7 +493,7 @@
 extern void	tcp_ddi_g_init(void);
 extern void	tcp_ddi_g_destroy(void);
 extern void 	*tcp_get_conn(void *arg, tcp_stack_t *);
-extern mblk_t	*tcp_snmp_get(queue_t *, mblk_t *);
+extern mblk_t	*tcp_snmp_get(queue_t *, mblk_t *, boolean_t);
 extern int	tcp_snmp_set(queue_t *, int, int, uchar_t *, int len);
 
 /*
--- a/usr/src/uts/common/inet/tcp/tcp_stats.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_stats.c	Fri Jul 23 16:52:46 2010 -0400
@@ -88,7 +88,7 @@
  * Return SNMP stuff in buffer in mpdata.
  */
 mblk_t *
-tcp_snmp_get(queue_t *q, mblk_t *mpctl)
+tcp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
 {
 	mblk_t			*mpdata;
 	mblk_t			*mp_conn_ctl = NULL;
@@ -114,6 +114,7 @@
 	ip_stack_t		*ipst;
 	mblk_t			*mp2ctl;
 	mib2_tcp_t		tcp_mib;
+	size_t			tcp_mib_size, tce_size, tce6_size;
 
 	/*
 	 * make a copy of the original message
@@ -138,6 +139,16 @@
 	ipst = connp->conn_netstack->netstack_ip;
 	tcps = connp->conn_netstack->netstack_tcp;
 
+	if (legacy_req) {
+		tcp_mib_size = LEGACY_MIB_SIZE(&tcp_mib, mib2_tcp_t);
+		tce_size = LEGACY_MIB_SIZE(&tce, mib2_tcpConnEntry_t);
+		tce6_size = LEGACY_MIB_SIZE(&tce6, mib2_tcp6ConnEntry_t);
+	} else {
+		tcp_mib_size = sizeof (mib2_tcp_t);
+		tce_size = sizeof (mib2_tcpConnEntry_t);
+		tce6_size = sizeof (mib2_tcp6ConnEntry_t);
+	}
+
 	bzero(&tcp_mib, sizeof (tcp_mib));
 
 	/* build table of connections -- need count in fixed part */
@@ -266,7 +277,7 @@
 			tce6.tcp6ConnCreationTime = connp->conn_open_time;
 
 			(void) snmp_append_data2(mp6_conn_ctl->b_cont,
-			    &mp6_conn_tail, (char *)&tce6, sizeof (tce6));
+			    &mp6_conn_tail, (char *)&tce6, tce6_size);
 
 			mlp.tme_connidx = v6_conn_idx++;
 			if (needattr)
@@ -333,7 +344,7 @@
 				tce.tcpConnCreationTime = connp->conn_open_time;
 
 				(void) snmp_append_data2(mp_conn_ctl->b_cont,
-				    &mp_conn_tail, (char *)&tce, sizeof (tce));
+				    &mp_conn_tail, (char *)&tce, tce_size);
 
 				mlp.tme_connidx = v4_conn_idx++;
 				if (needattr)
@@ -347,6 +358,10 @@
 
 	tcp_sum_mib(tcps, &tcp_mib);
 
+	/* Fixed length structure for IPv4 and IPv6 counters */
+	SET_MIB(tcp_mib.tcpConnTableSize, tce_size);
+	SET_MIB(tcp_mib.tcp6ConnTableSize, tce6_size);
+
 	/*
 	 * Synchronize 32- and 64-bit counters.  Note that tcpInSegs and
 	 * tcpOutSegs are not updated anywhere in TCP.  The new 64 bits
@@ -359,7 +374,7 @@
 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
 	optp->level = MIB2_TCP;
 	optp->name = 0;
-	(void) snmp_append_data(mpdata, (char *)&tcp_mib, sizeof (tcp_mib));
+	(void) snmp_append_data(mpdata, (char *)&tcp_mib, tcp_mib_size);
 	optp->len = msgdsize(mpdata);
 	qreply(q, mpctl);
 
@@ -567,6 +582,10 @@
 	bzero(&tcp_mib, sizeof (tcp_mib));
 	tcp_sum_mib(tcps, &tcp_mib);
 
+	/* Fixed length structure for IPv4 and IPv6 counters */
+	SET_MIB(tcp_mib.tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
+	SET_MIB(tcp_mib.tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
+
 	tcpkp->activeOpens.value.ui32 = tcp_mib.tcpActiveOpens;
 	tcpkp->passiveOpens.value.ui32 = tcp_mib.tcpPassiveOpens;
 	tcpkp->attemptFails.value.ui32 = tcp_mib.tcpAttemptFails;
@@ -855,10 +874,6 @@
 	cnt = tcps->tcps_sc_cnt;
 	for (i = 0; i < cnt; i++)
 		tcp_add_mib(&tcps->tcps_sc[i]->tcp_sc_mib, tcp_mib);
-
-	/* Fixed length structure for IPv4 and IPv6 counters */
-	SET_MIB(tcp_mib->tcpConnTableSize, sizeof (mib2_tcpConnEntry_t));
-	SET_MIB(tcp_mib->tcp6ConnTableSize, sizeof (mib2_tcp6ConnEntry_t));
 }
 
 /*
--- a/usr/src/uts/common/inet/udp/udp_stats.c	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/udp/udp_stats.c	Fri Jul 23 16:52:46 2010 -0400
@@ -48,7 +48,7 @@
  * information that can be changing beneath us.
  */
 mblk_t *
-udp_snmp_get(queue_t *q, mblk_t *mpctl)
+udp_snmp_get(queue_t *q, mblk_t *mpctl, boolean_t legacy_req)
 {
 	mblk_t			*mpdata;
 	mblk_t			*mp_conn_ctl;
@@ -76,6 +76,8 @@
 	udp_stack_t		*us = connp->conn_netstack->netstack_udp;
 	mblk_t			*mp2ctl;
 	mib2_udp_t		udp_mib;
+	size_t			udp_mib_size, ude_size, ude6_size;
+
 
 	/*
 	 * make a copy of the original message
@@ -99,10 +101,20 @@
 
 	zoneid = connp->conn_zoneid;
 
+	if (legacy_req) {
+		udp_mib_size = LEGACY_MIB_SIZE(&udp_mib, mib2_udp_t);
+		ude_size = LEGACY_MIB_SIZE(&ude, mib2_udpEntry_t);
+		ude6_size = LEGACY_MIB_SIZE(&ude6, mib2_udp6Entry_t);
+	} else {
+		udp_mib_size = sizeof (mib2_udp_t);
+		ude_size = sizeof (mib2_udpEntry_t);
+		ude6_size = sizeof (mib2_udp6Entry_t);
+	}
+
 	bzero(&udp_mib, sizeof (udp_mib));
 	/* fixed length structure for IPv4 and IPv6 counters */
-	SET_MIB(udp_mib.udpEntrySize, sizeof (mib2_udpEntry_t));
-	SET_MIB(udp_mib.udp6EntrySize, sizeof (mib2_udp6Entry_t));
+	SET_MIB(udp_mib.udpEntrySize, ude_size);
+	SET_MIB(udp_mib.udp6EntrySize, ude6_size);
 
 	udp_sum_mib(us, &udp_mib);
 
@@ -118,7 +130,7 @@
 	optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)];
 	optp->level = MIB2_UDP;
 	optp->name = 0;
-	(void) snmp_append_data(mpdata, (char *)&udp_mib, sizeof (udp_mib));
+	(void) snmp_append_data(mpdata, (char *)&udp_mib, udp_mib_size);
 	optp->len = msgdsize(mpdata);
 	qreply(q, mpctl);
 
@@ -236,7 +248,7 @@
 				ude.udpCreationTime = connp->conn_open_time;
 
 				(void) snmp_append_data2(mp_conn_ctl->b_cont,
-				    &mp_conn_tail, (char *)&ude, sizeof (ude));
+				    &mp_conn_tail, (char *)&ude, ude_size);
 				mlp.tme_connidx = v4_conn_idx++;
 				if (needattr)
 					(void) snmp_append_data2(
@@ -279,8 +291,7 @@
 				ude6.udp6CreationTime = connp->conn_open_time;
 
 				(void) snmp_append_data2(mp6_conn_ctl->b_cont,
-				    &mp6_conn_tail, (char *)&ude6,
-				    sizeof (ude6));
+				    &mp6_conn_tail, (char *)&ude6, ude6_size);
 				mlp.tme_connidx = v6_conn_idx++;
 				if (needattr)
 					(void) snmp_append_data2(
--- a/usr/src/uts/common/inet/udp_impl.h	Fri Jul 23 13:01:49 2010 -0700
+++ b/usr/src/uts/common/inet/udp_impl.h	Fri Jul 23 16:52:46 2010 -0400
@@ -236,7 +236,7 @@
 extern int	udp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
 extern int	udp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
 		    uint_t *, uchar_t *, void *, cred_t *);
-extern mblk_t	*udp_snmp_get(queue_t *, mblk_t *);
+extern mblk_t	*udp_snmp_get(queue_t *, mblk_t *, boolean_t);
 extern int	udp_snmp_set(queue_t *, t_scalar_t, t_scalar_t, uchar_t *, int);
 extern void	udp_ddi_g_init(void);
 extern void	udp_ddi_g_destroy(void);