svn commit: r253227 - in stable/9: etc etc/rc.d share/man/man5

Hiroki Sato hrs at FreeBSD.org
Fri Jul 12 00:40:50 UTC 2013


Author: hrs
Date: Fri Jul 12 00:40:49 2013
New Revision: 253227
URL: http://svnweb.freebsd.org/changeset/base/253227

Log:
  MFC 230453, 230726, 252015, 252426:
  
  - ipv6_enable + ipv6_gateway_enable should unset ACCEPT_RTADV by default for
    backward compatibility.
  
  - Configurations in ipv6_prefix_IF should be recognized even if there is no
    ifconfig_IF_ipv6.
  
  - DAD wait should be performed at once, not on a per-interface basis, if
    possible.  This fixes an issue that a system with a lot of IPv6-capable
    interfaces takes too long for booting.
  
  - Add CIDR notation support like 192.168.1-2.10-16/24 to $ifconfig_IF_aliasN.
    This is an extended version of ipv4_addr_IF which supports both IPv4 and
    IPv6, and multiple range specifications.  To avoid to generate too many
    addresses, the maximum number of the generated addresses is currently
    limited to 31.
  
  - Add $ifconfig_IF_aliases, which accepts multiple IP aliases in a variable.
  
  - ipv6_prefix_IF now supports !/64 prefix length.  In addition to the old
    64-bit format (2001:db8:1:1), a full 128-bit format like 2001:db8:1:1::/64
    is supported.
  
  - Replace ifconfig command with $IFCONFIG_CMD variable to support
    a dry-run mode in the future.
  
  - Remove IP aliases before removing all of IPv4 addresses when doing
    "rc.d/netif down".
  
  - Add a DAD wait to network6_getladdr() because it is possible to fail to
    configure an EUI64 address when ipv6_prefix_IF is specified.

Modified:
  stable/9/etc/network.subr
  stable/9/etc/rc.d/netif
  stable/9/share/man/man5/rc.conf.5
Directory Properties:
  stable/9/etc/   (props changed)
  stable/9/etc/rc.d/   (props changed)
  stable/9/share/man/man5/   (props changed)

Modified: stable/9/etc/network.subr
==============================================================================
--- stable/9/etc/network.subr	Thu Jul 11 23:35:51 2013	(r253226)
+++ stable/9/etc/network.subr	Fri Jul 12 00:40:49 2013	(r253227)
@@ -24,6 +24,10 @@
 #
 # $FreeBSD$
 #
+IFCONFIG_CMD="/sbin/ifconfig"
+
+# Maximum number of addresses expanded from a address range specification.
+_IPEXPANDMAX=31
 
 #
 # Subroutines commonly used from network startup scripts.
@@ -94,7 +98,7 @@ ifconfig_up()
 	# ifconfig_IF
 	ifconfig_args=`ifconfig_getargs $1`
 	if [ -n "${ifconfig_args}" ]; then
-		eval ifconfig $1 ${ifconfig_args}
+		eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
 		_cfg=0
 	fi
 
@@ -122,7 +126,7 @@ ifconfig_up()
 		esac
 
 		if [ -n "${_ipv6_opts}" ]; then
-			ifconfig $1 inet6 ${_ipv6_opts}
+			${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts}
 		fi
 
 		# ifconfig_IF_ipv6
@@ -136,24 +140,35 @@ ifconfig_up()
 				ifconfig_args="inet6 ${ifconfig_args}"
 			;;
 			esac
-			ifconfig $1 inet6 -ifdisabled
-			eval ifconfig $1 ${ifconfig_args}
+			${IFCONFIG_CMD} $1 inet6 -ifdisabled
+			eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
+			_cfg=0
+		fi
+
+		# $ipv6_prefix_IF will be handled in
+		# ipv6_prefix_hostid_addr_common().
+		ifconfig_args=`get_if_var $1 ipv6_prefix_IF`
+		if [ -n "${ifconfig_args}" ]; then
+			${IFCONFIG_CMD} $1 inet6 -ifdisabled
 			_cfg=0
 		fi
 
-		# backward compatiblity: $ipv6_ifconfig_IF
+		# backward compatibility: $ipv6_ifconfig_IF
 		ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF`
 		if [ -n "${ifconfig_args}" ]; then
 			warn "\$ipv6_ifconfig_$1 is obsolete." \
 			    "  Use ifconfig_$1_ipv6 instead."
-			ifconfig $1 inet6 -ifdisabled
-			eval ifconfig $1 inet6 ${ifconfig_args}
+			${IFCONFIG_CMD} $1 inet6 -ifdisabled
+			eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args}
 			_cfg=0
 		fi
 	fi
 
+	ifalias $1 link alias
+	ifalias $1 ether alias
+
 	if [ ${_cfg} -eq 0 ]; then
-		ifconfig $1 up
+		${IFCONFIG_CMD} $1 up
 	fi
 
 	if wpaif $1; then
@@ -166,7 +181,7 @@ ifconfig_up()
 
 	if dhcpif $1; then
 		if [ $_cfg -ne 0 ] ; then
-			ifconfig $1 up
+			${IFCONFIG_CMD} $1 up
 		fi
 		if syncdhcpif $1; then
 			/etc/rc.d/dhclient start $1
@@ -200,7 +215,7 @@ ifconfig_down()
 	fi
 
 	if ifexists $1; then
-		ifconfig $1 down
+		${IFCONFIG_CMD} $1 down
 		_cfg=0
 	fi
 
@@ -420,6 +435,9 @@ afexists()
 			return 1
 		fi
 		;;
+	link|ether)
+		return 0
+		;;
 	*)
 		err 1 "afexists(): Unsupported address family: $_af"
 		;;
@@ -559,7 +577,7 @@ ipv6_autoconfif()
 ifexists()
 {
 	[ -z "$1" ] && return 1
-	ifconfig -n $1 > /dev/null 2>&1
+	${IFCONFIG_CMD} -n $1 > /dev/null 2>&1
 }
 
 # ipv4_up if
@@ -574,11 +592,10 @@ ipv4_up()
 	if [ "${_if}" = "lo0" ]; then
 		ifconfig_args=`get_if_var ${_if} ifconfig_IF`
 		if [ -z "${ifconfig_args}" ]; then
-			ifconfig ${_if} inet 127.0.0.1/8 alias
+			${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias
 		fi
 	fi
-	ifalias_up ${_if} inet && _ret=0
-	ipv4_addrs_common ${_if} alias && _ret=0
+	ifalias ${_if} inet alias && _ret=0
 
 	return $_ret
 }
@@ -595,7 +612,7 @@ ipv6_up()
 		return 0
 	fi
 
-	ifalias_up ${_if} inet6 && _ret=0
+	ifalias ${_if} inet6 alias && _ret=0
 	ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0
 	ipv6_accept_rtadv_up ${_if} && _ret=0
 
@@ -615,7 +632,9 @@ ipv4_down()
 	_ifs="^"
 	_ret=1
 
-	inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`"
+	ifalias ${_if} inet -alias && _ret=0
+
+	inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n" "$_ifs"`"
 
 	oldifs="$IFS"
 	IFS="$_ifs"
@@ -626,15 +645,12 @@ ipv4_down()
 		_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
 
 		IFS="$oldifs"
-		ifconfig ${_if} ${_inet} delete
+		${IFCONFIG_CMD} ${_if} ${_inet} delete
 		IFS="$_ifs"
 		_ret=0
 	done
 	IFS="$oldifs"
 
-	ifalias_down ${_if} inet && _ret=0
-	ipv4_addrs_common ${_if} -alias && _ret=0
-
 	return $_ret
 }
 
@@ -653,9 +669,9 @@ ipv6_down()
 
 	ipv6_accept_rtadv_down ${_if} && _ret=0
 	ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0
-	ifalias_down ${_if} inet6 && _ret=0
+	ifalias ${_if} inet6 -alias && _ret=0
 
-	inetList="`ifconfig ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`"
+	inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`"
 
 	oldifs="$IFS"
 	IFS="$_ifs"
@@ -666,7 +682,7 @@ ipv6_down()
 		_inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'`
 
 		IFS="$oldifs"
-		ifconfig ${_if} ${_inet6} -alias
+		${IFCONFIG_CMD} ${_if} ${_inet6} -alias
 		IFS="$_ifs"
 		_ret=0
 	done
@@ -675,234 +691,356 @@ ipv6_down()
 	return $_ret
 }
 
-# ipv4_addrs_common if action
-#	Evaluate the ifconfig_if_ipv4 arguments for interface $if and
-#	use $action to add or remove IPv4 addresses from $if.
-ipv4_addrs_common()
-{
-	local _ret _if _action _cidr _cidr_addr
-	local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount
-	_ret=1
-	_if=$1
-	_action=$2
-
-	# get ipv4-addresses
-	cidr_addr=`get_if_var $_if ipv4_addrs_IF`
-
-	for _cidr in ${cidr_addr}; do
-		_ipaddr=${_cidr%%/*}
-		_netmask="/"${_cidr##*/}
-		_range=${_ipaddr##*.}
-		_ipnet=${_ipaddr%.*}
-		_iplow=${_range%-*}
-		_iphigh=${_range#*-}
-
-		# clear netmask when removing aliases
-		if [ "${_action}" = "-alias" ]; then
-			_netmask=""
-		fi
-
-		_ipcount=${_iplow}
-		while [ "${_ipcount}" -le "${_iphigh}" ]; do
-			eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}"
-			_ipcount=$((${_ipcount}+1))
-			_ret=0
-
-			# only the first ipaddr in a subnet need the real netmask
-			if [ "${_action}" != "-alias" ]; then
-				_netmask="/32"
-			fi
-		done
-	done
-
-	return $_ret
-}
-
-# ifalias_up if af
-#	Configure aliases for network interface $if.
+# ifalias if af action
+#	Configure or remove aliases for network interface $if.
 #	It returns 0 if at least one alias was configured or
-#	1 if there were none.
+#	removed, or 1 if there were none.
 #
-ifalias_up()
+ifalias()
 {
 	local _ret
 	_ret=1
 
+	afexists $2 || return $_ret
+
 	case "$2" in
-	inet)
-		_ret=`ifalias_ipv4_up "$1"`
-		;;
-	inet6)
-		_ret=`ifalias_ipv6_up "$1"`
+	inet|inet6|link|ether)
+		ifalias_af_common $1 $2 $3 && _ret=0
 		;;
 	esac
 
 	return $_ret
 }
 
-# ifalias_ipv4_up if
-#	Helper function for ifalias_up().  Handles IPv4.
+# ifalias_expand_addr af action addr
+#	Expand address range ("N-M") specification in addr.
+#	"addr" must not include an address-family keyword.
+#	The results will include an address-family keyword.
 #
-ifalias_ipv4_up()
+ifalias_expand_addr()
 {
-	local _ret alias ifconfig_args
-	_ret=1
-
-	# ifconfig_IF_aliasN which starts with "inet"
-	alias=0
-	while : ; do
-		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		inet\ *)
-			ifconfig $1 ${ifconfig_args} alias && _ret=0
-			;;
-		inet6\ *)
-			;;
-		"")
-			break
-			;;
-		*)
-			warn "\$ifconfig_$1_alias${alias} needs " \
-			    "\"inet\" keyword for an IPv4 address."
-			ifconfig $1 ${ifconfig_args} alias && _ret=0
-			;;
-		esac
-		alias=$((${alias} + 1))
-	done
 
-	return $_ret
+	afexists $1 || return
+	ifalias_expand_addr_$1 $2 $3
 }
 
-# ifalias_ipv6_up if
-#	Helper function for ifalias_up().  Handles IPv6.
+# ifalias_expand_addr_inet action addr
+#	Helper function for ifalias_expand_addr().  Handles IPv4.
 #
-ifalias_ipv6_up()
+ifalias_expand_addr_inet()
 {
-	local _ret alias ifconfig_args
-	_ret=1
+	local _action _arg _cidr _cidr_addr
+	local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount
+	local _retstr _c
+	_action=$1
+	_arg=$2
+	_retstr=
 
-	# ifconfig_IF_aliasN which starts with "inet6"
-	alias=0
-	while : ; do
-		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		inet6\ *)
-			ifconfig $1 ${ifconfig_args} alias && _ret=0
-			;;
-		"")
-			break
-			;;
+	case $_action:$_arg in
+	*:*--*)		return ;;			# invalid
+	tmp:*)		echo $_arg && return ;;		# already expanded
+	tmp:*-*)	_action="alias"	;;		# to be expanded
+	*:*-*)		;;				# to be expanded
+	*:*)		echo inet $_arg && return ;;	# already expanded
+	esac
+
+	for _cidr in $_arg; do
+		_ipaddr=${_cidr%%/*}
+		_plen=${_cidr##*/}
+		# When subnet prefix length is not specified, use /32.
+		case $_plen in
+		$_ipaddr)	_plen=32 ;;	# "/" character not found
 		esac
-		alias=$((${alias} + 1))
-	done
 
-	# backward compatibility: ipv6_ifconfig_IF_aliasN.
-	alias=0
-	while : ; do
-		ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		"")
-			break
+		OIFS=$IFS
+		IFS=. set -- $_ipaddr
+		_range=
+		_iphead=
+		_iptail=
+		for _c in $@; do
+			case $_range:$_c in
+			:[0-9]*-[0-9]*)
+				_range=$_c
 			;;
-		*)
-			ifconfig $1 inet6 ${ifconfig_args} alias && _ret=0
-			warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \
-			    "  Use ifconfig_$1_aliasN instead."
+			:*)
+				_iphead="${_iphead}${_iphead:+.}${_c}"
 			;;
-		esac
-		alias=$((${alias} + 1))
+			*:*)
+				_iptail="${_iptail}${_iptail:+.}${_c}"
+			;;
+			esac
+		done
+		IFS=$OIFS
+		_iplow=${_range%-*}
+		_iphigh=${_range#*-}
+
+		# clear netmask when removing aliases
+		if [ "$_action" = "-alias" ]; then
+			_plen=""
+		fi
+
+		_ipcount=$_iplow
+		while [ "$_ipcount" -le "$_iphigh" ]; do
+			_retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}"
+			if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]; then
+				warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}).  ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed."
+				break
+			else
+				_ipcount=$(($_ipcount + 1))
+			fi
+			# Forcibly set /32 for remaining aliases.
+			_plen=32
+		done
 	done
 
-	return $_ret
+	for _c in $_retstr; do
+		ifalias_expand_addr_inet $_action $_c
+	done
 }
 
-# ifalias_down if af
-#	Remove aliases for network interface $if.
-#	It returns 0 if at least one alias was removed or
-#	1 if there were none.
+# ifalias_expand_addr_inet6 action addr
+#	Helper function for ifalias_expand_addr().  Handles IPv6.
 #
-ifalias_down()
-{
-	local _ret
-	_ret=1
-
-	case "$2" in
-	inet)
-		_ret=`ifalias_ipv4_down "$1"`
-		;;
-	inet6)
-		_ret=`ifalias_ipv6_down "$1"`
-		;;
+ifalias_expand_addr_inet6()
+{
+	local _action _arg _cidr _cidr_addr
+	local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount
+	local _ipv4part
+	local _retstr _c
+	_action=$1
+	_arg=$2
+	_retstr=
+
+	case $_action:$_arg in
+	*:*--*)		return ;;			# invalid
+	tmp:*)		echo $_arg && return ;;
+	tmp:*-*)	_action="alias"	;;
+	*:*-*)		;;
+	*:*)		echo inet6 $_arg && return ;;
 	esac
 
-	return $_ret
+	for _cidr in $_arg; do
+		_ipaddr="${_cidr%%/*}"
+		_plen="${_cidr##*/}"
+
+		case $_action:$_ipaddr:$_cidr in
+		-alias:*:*)		unset _plen ;;
+		*:$_cidr:$_ipaddr)	unset _plen ;;
+		esac
+
+		if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then
+			# Handle !v4mapped && !v4compat addresses.
+
+			# The default prefix length is 64.
+			case $_ipaddr:$_cidr in
+			$_cidr:$_ipaddr)	_plen="64" ;;
+			esac
+			_ipleft=${_ipaddr%-*}
+			_ipright=${_ipaddr#*-}
+			_iplow=${_ipleft##*:}
+			_iphigh=${_ipright%%:*}
+			_ipleft=${_ipleft%:*}
+			_ipright=${_ipright#*:}
+
+			if [ "$_iphigh" = "$_ipright" ]; then
+				unset _ipright
+			else
+				_ipright=:$_ipright
+			fi
+
+			if [ -n "$_iplow" -a -n "$_iphigh" ]; then
+				_iplow=$((0x$_iplow))
+				_iphigh=$((0x$_iphigh))
+				_ipcount=$_iplow
+				while [ $_ipcount -le $_iphigh ]; do
+					_r=`printf "%s:%04x%s%s" \
+					    $_ipleft $_ipcount $_ipright \
+					    ${_plen:+/}$_plen`
+					_retstr="$_retstr $_r"
+					if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]
+					then
+						warn "Range specification is too large $(printf '(%s:%04x%s-%s:%04x%s)' $_ipleft $_iplow $_ipright $_ipleft $_iphigh $_ipright). $(printf '%s:%04x%s-%s:%04x%s' $_ipleft $_iplow $_ipright $_ipleft $_ipcount $_ipright) was processed."
+						break
+					else
+						_ipcount=$(($_ipcount + 1))
+					fi
+				done
+			else
+				_retstr="${_ipaddr}${_plen:+/}${_plen}"
+			fi
+
+			for _c in $_retstr; do
+				ifalias_expand_addr_inet6 $_action $_c
+			done
+		else
+			# v4mapped/v4compat should handle as an IPv4 alias
+			_ipv4part=${_ipaddr##*:}
+
+			# Adjust prefix length if any.  If not, set the
+			# default prefix length as 32.
+			case $_ipaddr:$_cidr in
+			$_cidr:$_ipaddr)	_plen=32 ;;
+			*)			_plen=$(($_plen - 96)) ;;
+			esac
+
+			_retstr=`ifalias_expand_addr_inet \
+			    tmp ${_ipv4part}${_plen:+/}${_plen}`
+			for _c in $_retstr; do
+				ifalias_expand_addr_inet $_action $_c
+			done
+		fi
+	done
 }
 
-# ifalias_ipv4_down if
-#	Helper function for ifalias_down().  Handles IPv4.
+# ifalias_af_common_handler if af action args
+#	Helper function for ifalias_af_common().
 #
-ifalias_ipv4_down()
+ifalias_af_common_handler()
 {
-	local _ret alias ifconfig_args
+	local _ret _if _af _action _args _c _tmpargs
+
 	_ret=1
+	_if=$1
+	_af=$2
+	_action=$3
+	shift 3
+	_args=$*
+
+	case $_args in
+	${_af}\ *)	;;
+	*)	return	;;
+	esac
 
-	# ifconfig_IF_aliasN which starts with "inet"
-	alias=0
-	while : ; do
-		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		inet\ *)
-			ifconfig $1 ${ifconfig_args} -alias && _ret=0
+	# link(ether) does not support address removal.
+	case $_af:$_action in
+	link:-alias|ether:-alias)	return ;;
+	esac
+
+	_tmpargs=
+	for _c in $_args; do
+		case $_c in
+		${_af})
+			case $_tmpargs in
+			${_af}\ *-*)
+				ifalias_af_common_handler $_if $_af $_action \
+				`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
 			;;
-		"")
-			break
+			${_af}\ *)
+				${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
 			;;
+			esac
+			_tmpargs=$_af
+		;;
+		*)
+			_tmpargs="$_tmpargs $_c"
+		;;
 		esac
-		alias=$((${alias} + 1))
 	done
+	# Process the last component if any.
+	if [ -n "$_tmpargs}" ]; then
+		case $_tmpargs in
+		${_af}\ *-*)
+			ifalias_af_common_handler $_if $_af $_action \
+			`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
+		;;
+		${_af}\ *)
+			${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
+		;;
+		esac
+	fi
 
 	return $_ret
 }
 
-# ifalias_ipv6_down if
-#	Helper function for ifalias_down().  Handles IPv6.
+# ifalias_af_common if af action
+#	Helper function for ifalias().
 #
-ifalias_ipv6_down()
+ifalias_af_common()
 {
-	local _ret alias ifconfig_args
+	local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf
+
 	_ret=1
+	_aliasn=
+	_if=$1
+	_af=$2
+	_action=$3
 
-	# ifconfig_IF_aliasN which starts with "inet6"
+	# ifconfig_IF_aliasN which starts with $_af
 	alias=0
 	while : ; do
-		ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		inet6\ *)
-			ifconfig $1 ${ifconfig_args} -alias && _ret=0
+		ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}`
+		_iaf=
+		case $ifconfig_args in
+		inet\ *)	_iaf=inet ;;
+		inet6\ *)	_iaf=inet6 ;;
+		ipx\ *)		_iaf=ipx ;;
+		link\ *)	_iaf=link ;;
+		ether\ *)	_iaf=ether ;;
+		esac
+
+		case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in
+		${_af}:*:${_af}:*)
+			_aliasn="$_aliasn $ifconfig_args"
 			;;
-		"")
+		${_af}:*:"":"")
 			break
 			;;
+		inet:alias:"":*)
+			_aliasn="$_aliasn inet $ifconfig_args"
+			warn "\$ifconfig_${_if}_alias${alias} needs " \
+			    "\"inet\" keyword for an IPv4 address."
 		esac
-		alias=$((${alias} + 1))
+		alias=$(($alias + 1))
 	done
 
 	# backward compatibility: ipv6_ifconfig_IF_aliasN.
-	alias=0
-	while : ; do
-		ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}`
-		case "${ifconfig_args}" in
-		"")
-			break
+	case $_af in
+	inet6)
+		alias=0
+		while : ; do
+			ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}`
+			case ${_action}:"${ifconfig_args}" in
+			*:"")
+				break
+			;;
+			alias:*)
+				_aliasn="${_aliasn} inet6 ${ifconfig_args}"
+				warn "\$ipv6_ifconfig_${_if}_alias${alias} " \
+				    "is obsolete.  Use ifconfig_$1_aliasN " \
+				    "instead."
 			;;
-		*)
-			ifconfig $1 inet6 ${ifconfig_args} -alias && _ret=0
-			warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \
-			    "  Use ifconfig_$1_aliasN instead."
+			esac
+			alias=$(($alias + 1))
+		done
+	esac
+
+	# backward compatibility: ipv4_addrs_IF.
+	for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do
+		_aliasn="$_aliasn inet $_tmpargs"
+	done
+
+	# Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others.
+	_tmpargs=
+	for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do
+		case $_c in
+		inet|inet6|ipx|link|ether)
+			case $_tmpargs in
+			${_af}\ *)
+				eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
 			;;
+			esac
+			_tmpargs=$_c
+		;;
+		*)
+			_tmpargs="$_tmpargs $_c"
 		esac
-		alias=$((${alias} + 1))
 	done
+	# Process the last component
+	case $_tmpargs in
+	${_af}\ *)
+		ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
+	;;
+	esac
 
 	return $_ret
 }
@@ -923,14 +1061,32 @@ ipv6_prefix_hostid_addr_common()
 		hostid=${hostid%\%*}
 
 		for j in ${prefix}; do
-			address=$j\:${hostid}
-			ifconfig ${_if} inet6 ${address} prefixlen 64 ${_action}
+			# The default prefixlen is 64.
+			plen=${j#*/}
+			case $j:$plen in
+			$plen:$j)	plen=64 ;;
+			*)		j=${j%/*} ;;
+			esac
+
+			# Normalize the last part by removing ":"
+			j=${j%:*}
+			j=${j%:}
+			OIFS=$IFS; IFS=":"; set -- $j; nj=$#; IFS=$OIFS
+			OIFS=$IFS; IFS=":"; set -- $hostid; nh=$#; IFS=$OIFS
+			if [ $(($nj + $nh)) -eq 8 ]; then
+				address=$j\:$hostid
+			else
+				address=$j\::$hostid
+			fi
+
+			${IFCONFIG_CMD} ${_if} inet6 ${address} \
+				prefixlen $plen ${_action}
 
 			# if I am a router, add subnet router
 			# anycast address (RFC 2373).
 			if checkyesno ipv6_gateway_enable; then
-				ifconfig ${_if} inet6 $j:: prefixlen 64 \
-					${_action} anycast
+				${IFCONFIG_CMD} ${_if} inet6 $j:: \
+					prefixlen $plen ${_action} anycast
 			fi
 		done
 	fi
@@ -942,7 +1098,7 @@ ipv6_prefix_hostid_addr_common()
 ipv6_accept_rtadv_up()
 {
 	if ipv6_autoconfif $1; then
-		ifconfig $1 inet6 accept_rtadv up
+		${IFCONFIG_CMD} $1 inet6 accept_rtadv up
 		if ! checkyesno rtsold_enable; then
 			rtsol ${rtsol_flags} $1
 		fi
@@ -954,7 +1110,7 @@ ipv6_accept_rtadv_up()
 ipv6_accept_rtadv_down()
 {
 	if ipv6_autoconfif $1; then
-		ifconfig $1 inet6 -accept_rtadv
+		${IFCONFIG_CMD} $1 inet6 -accept_rtadv
 	fi
 }
 
@@ -999,7 +1155,7 @@ clone_up()
 
 	# create_args_IF
 	for ifn in ${cloned_interfaces}; do
-		ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF`
+		${IFCONFIG_CMD} ${ifn} create `get_if_var ${ifn} create_args_IF`
 		if [ $? -eq 0 ]; then
 			_list="${_list}${_prefix}${ifn}"
 			[ -z "$_prefix" ] && _prefix=' '
@@ -1019,7 +1175,7 @@ clone_down()
 	_list=
 
 	for ifn in ${cloned_interfaces}; do
-		ifconfig -n ${ifn} destroy
+		${IFCONFIG_CMD} -n ${ifn} destroy
 		if [ $? -eq 0 ]; then
 			_list="${_list}${_prefix}${ifn}"
 			[ -z "$_prefix" ] && _prefix=' '
@@ -1046,16 +1202,16 @@ childif_create()
 		debug_flags="`get_if_var $child wlandebug_IF`"
 
 		if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then
-			ifconfig $child create ${create_args} && cfg=0
+			${IFCONFIG_CMD} $child create ${create_args} && cfg=0
 			if [ -n "${debug_flags}" ]; then
 				wlandebug -i $child ${debug_flags}
 			fi
 		else
-			i=`ifconfig wlan create ${create_args}`
+			i=`${IFCONFIG_CMD} wlan create ${create_args}`
 			if [ -n "${debug_flags}" ]; then
 				wlandebug -i $i ${debug_flags}
 			fi
-			ifconfig $i name $child && cfg=0
+			${IFCONFIG_CMD} $i name $child && cfg=0
 		fi
 		if autoif $child; then
 			ifn_start $child
@@ -1073,14 +1229,14 @@ childif_create()
 		if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
 			child="${ifn}.${child}"
 			create_args=`get_if_var $child create_args_IF`
-			ifconfig $child create ${create_args} && cfg=0
+			${IFCONFIG_CMD} $child create ${create_args} && cfg=0
 		else
 			create_args="vlandev $ifn `get_if_var $child create_args_IF`"
 			if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then
-				ifconfig $child create ${create_args} && cfg=0
+				${IFCONFIG_CMD} $child create ${create_args} && cfg=0
 			else
-				i=`ifconfig vlan create ${create_args}`
-				ifconfig $i name $child && cfg=0
+				i=`${IFCONFIG_CMD} vlan create ${create_args}`
+				${IFCONFIG_CMD} $i name $child && cfg=0
 			fi
 		fi
 		if autoif $child; then
@@ -1104,7 +1260,7 @@ childif_destroy()
 		if ! ifexists $child; then
 			continue
 		fi
-		ifconfig -n $child destroy && cfg=0
+		${IFCONFIG_CMD} -n $child destroy && cfg=0
 	done
 
 	child_vlans=`get_if_var $ifn vlans_IF`
@@ -1115,7 +1271,7 @@ childif_destroy()
 		if ! ifexists $child; then
 			continue
 		fi
-		ifconfig -n $child destroy && cfg=0
+		${IFCONFIG_CMD} -n $child destroy && cfg=0
 	done
 
 	return ${cfg}
@@ -1162,13 +1318,13 @@ gif_up()
 			;;
 		*)
 			if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then
-				ifconfig $i create >/dev/null 2>&1
+				${IFCONFIG_CMD} $i create >/dev/null 2>&1
 			else
-				gif=`ifconfig gif create`
-				ifconfig $gif name $i
+				gif=`${IFCONFIG_CMD} gif create`
+				${IFCONFIG_CMD} $gif name $i
 			fi
-			ifconfig $i tunnel ${peers}
-			ifconfig $i up
+			${IFCONFIG_CMD} $i tunnel ${peers}
+			${IFCONFIG_CMD} $i up
 			;;
 		esac
 	done
@@ -1234,7 +1390,7 @@ ipx_up()
 	# ifconfig_IF_ipx
 	ifconfig_args=`_ifconfig_getargs $ifn ipx`
 	if [ -n "${ifconfig_args}" ]; then
-		ifconfig ${ifn} ${ifconfig_args}
+		${IFCONFIG_CMD} ${ifn} ${ifconfig_args}
 		return 0
 	fi
 
@@ -1251,7 +1407,7 @@ ipx_down()
 	_if=$1
 	_ifs="^"
 	_ret=1
-	ipxList="`ifconfig ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`"
+	ipxList="`${IFCONFIG_CMD} ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`"
 	oldifs="$IFS"
 
 	IFS="$_ifs"
@@ -1262,7 +1418,7 @@ ipx_down()
 		_ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
 
 		IFS="$oldifs"
-		ifconfig ${_if} ${_ipx} delete
+		${IFCONFIG_CMD} ${_if} ${_ipx} delete
 		IFS="$_ifs"
 		_ret=0
 	done
@@ -1279,10 +1435,10 @@ ifnet_rename()
 	local _if _ifname
 
 	# ifconfig_IF_name
-	for _if in `ifconfig -l`; do
+	for _if in `${IFCONFIG_CMD} -l`; do
 		_ifname=`get_if_var $_if ifconfig_IF_name`
 		if [ ! -z "$_ifname" ]; then
-			ifconfig $_if name $_ifname
+			${IFCONFIG_CMD} $_if name $_ifname
 		fi
 	done
 
@@ -1314,7 +1470,7 @@ list_net_interfaces()
 	_tmplist=
 	case ${network_interfaces} in
 	[Aa][Uu][Tt][Oo])
-		_autolist="`ifconfig -l`"
+		_autolist="`${IFCONFIG_CMD} -l`"
 		_lo=
 		for _if in ${_autolist} ; do
 			if autoif $_if; then
@@ -1422,7 +1578,7 @@ is_wired_interface()
 {
 	local media
 
-	case `ifconfig $1 2>/dev/null` in
+	case `${IFCONFIG_CMD} $1 2>/dev/null` in
 	*media:?Ethernet*) media=Ethernet ;;
 	esac
 
@@ -1434,25 +1590,27 @@ is_wired_interface()
 #	If flag is defined, tentative ones will be excluded.
 network6_getladdr()
 {
-	local proto addr rest
-	ifconfig $1 2>/dev/null | while read proto addr rest; do
-		case ${proto} in
-		inet6)
-			case ${addr} in
-			fe80::*)
-				if [ -z "$2" ]; then
-					echo ${addr}
-					return
-				fi
-				case ${rest} in
-				*tentative*)
-					continue
-					;;
-				*)
-					echo ${addr}
-					return
-				esac
-			esac
+	local _if _flag proto addr rest
+	_if=$1
+	_flag=$2
+
+	${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do
+		case "${proto}/${addr}/${_flag}/${rest}" in
+		inet6/fe80::*//*)
+			echo ${addr}
+		;;
+		inet6/fe80:://*tentative*)	# w/o flag
+			sleep `${SYSCTL_N} net.inet6.ip6.dad_count`
+			network6_getladdr $_if $_flags
+		;;
+		inet6/fe80::/*/*tentative*)	# w/ flag
+			echo ${addr}
+		;;
+		*)
+			continue
+		;;
 		esac
+
+		return
 	done
 }

Modified: stable/9/etc/rc.d/netif
==============================================================================
--- stable/9/etc/rc.d/netif	Thu Jul 11 23:35:51 2013	(r253226)
+++ stable/9/etc/rc.d/netif	Fri Jul 12 00:40:49 2013	(r253227)
@@ -123,16 +123,28 @@ network_common()
 		_cooked_list="`list_net_interfaces`"
 	fi
 
+	_dadwait=
 	_fail=
 	_ok=
 	for ifn in ${_cooked_list}; do
 		if ${_func} ${ifn} $2; then
 			_ok="${_ok} ${ifn}"
+			if ipv6if ${ifn}; then
+				_dadwait=1
+			fi
 		else
 			_fail="${_fail} ${ifn}"
 		fi
 	done
 
+	# inet6 address configuration needs sleep for DAD.
+	case ${_func}:${_dadwait} in
+	ifn_start:1)
+		sleep `${SYSCTL_N} net.inet6.ip6.dad_count`
+		sleep 1
+	;;
+	esac
+
 	_str=
 	if [ -n "${_ok}" ]; then
 		case ${_func} in

Modified: stable/9/share/man/man5/rc.conf.5
==============================================================================
--- stable/9/share/man/man5/rc.conf.5	Thu Jul 11 23:35:51 2013	(r253226)
+++ stable/9/share/man/man5/rc.conf.5	Fri Jul 12 00:40:49 2013	(r253227)
@@ -24,7 +24,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 22, 2012
+.Dd June 20, 2013
 .Dt RC.CONF 5
 .Os
 .Sh NAME

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-9 mailing list