From ecb1515d96a659496e4eae2df3d9ef822c78b3de Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Fri, 16 Sep 2011 15:07:10 +0200
Subject: [PATCH 1/4] Wait for link and ipv6 duplicate address detection

Fixed to wait until link becomes ready and ipv6 duplicate address
detection finished what can cause failures of further services.
Added LINK_READY_WAIT and IPV6_DAD_WAIT variables (bnc#697929).

Signed-off-by: Marius Tomaschewski <mt@suse.com>
---
 config/sysconfig.config-network |   17 ++++++++
 scripts/functions               |   75 +++++++++++++++++++++++++++++++++++
 scripts/ifup                    |   82 +++++++++++++++++++++++++++++++++++----
 3 files changed, 166 insertions(+), 8 deletions(-)

diff --git a/config/sysconfig.config-network b/config/sysconfig.config-network
index 1b358ea..de045f8 100644
--- a/config/sysconfig.config-network
+++ b/config/sysconfig.config-network
@@ -143,6 +143,23 @@ MANDATORY_DEVICES=""
 #
 WAIT_FOR_INTERFACES="30"
 
+## Type:        integer
+## Default:     ""
+#
+# The number of seconds to wait for link to become useable / ready.
+# Default is to use WAIT_FOR_INTERFACES/2 seconds. Set to 0 to disable.
+#
+LINK_READY_WAIT=""
+
+## Type:        integer
+## Default:     ""
+#
+# The number of seconds to wait for the end of IPv6 duplicate address
+# detection. Default is to use WAIT_FOR_INTERFACES/5 seconds. Set to
+# 0 to disable.
+#
+IPV6_DAD_WAIT=""
+
 ## Type:	yesno
 ## Default:	yes
 #
diff --git a/scripts/functions b/scripts/functions
index b57f309..c1f1e9c 100644
--- a/scripts/functions
+++ b/scripts/functions
@@ -121,6 +121,81 @@ is_iface_up () {
 	esac
 }
 
+link_ready_check () {
+        local c=`cat /sys/class/net/${1}/carrier 2>/dev/null`
+        local d=`cat /sys/class/net/${1}/dormant 2>/dev/null`
+        local o=`cat /sys/class/net/${1}/operstate 2>/dev/null`
+
+        #debug "link ready ${1}: carrier=$c, dormant=$d, operstate=$o"
+        if test -e "/sys/class/net/${1}/operstate" ; then
+                # SLE 11 has carrier + operstate + dormant
+		test "$d" = "0" || return 3
+		test "$c" = "1" || return 2
+		test \( "$o" = "up" -o "$o" = "unknown" \) || return 1
+        else
+                # e.g. SLE 10 does not have operstate/dormant
+                test "$c" = "1" || return 1
+        fi
+	return 0
+}
+
+link_ready_wait () {
+	local iface=$1
+	local wsecs=${2:-0}
+	local uwait=25000
+	local loops=$(((wsecs * 100000) / $uwait))
+	local loop ret=0
+	for((loop=0; loop < $loops; loop++)) ; do
+		link_ready_check "$iface" ; ret=$?
+		test $ret -ne 0 && usleep $uwait || break
+	done
+	return $ret
+}
+
+ipv6_addr_dad_check()
+{
+	local iface="$1" word i
+	local nodad=1 tentative=1 dadfailed=1
+	test -f "/sys/class/net/$iface/ifindex" || return 1
+	while read -a word ; do
+		test "${word[0]}" != "inet6" && continue
+		for((i=2; i<${#word[@]}; ++i)) ; do
+			case ${word[$i]} in
+			nodad)		nodad=0     ;;
+			tentative)	tentative=0 ;;
+			dadfailed)	dadfailed=0 ;;
+			flags)  ((i++))
+				rx='^[[:xdigit:]]+$'
+				[[ "${word[$i]}" =~ $rx ]] || continue
+				hx="0x${word[$i]}"
+				test $(( $hx & 0x02 )) -ne 0 && nodad=0
+				test $(( $hx & 0x08 )) -ne 0 && dadfailed=0
+				test $(( $hx & 0x40 )) -ne 0 && tentative=0
+			;;
+			esac
+		done
+		#debug "ipv6 dad $iface: nodad=$nodad, dadfailed=$dadfailed, tentative=$tentative"
+		test $nodad     -eq 0 && continue
+		test $dadfailed -eq 0 && return 2
+		test $tentative -eq 0 && return 3
+	done < <(LC_ALL=C ip -6 addr show ${iface:+dev "$iface"} 2>/dev/null)
+	return $R_SUCCESS
+}
+
+ipv6_addr_dad_wait()
+{
+	local iface=$1
+	local wsecs=${2:-0}
+	local uwait=25000
+	local loops=$(((wsecs * 100000) / $uwait))
+	local loop ret=0
+	for((loop=0; loop < $loops; loop++)) ; do
+		ipv6_addr_dad_check "$iface" ; ret=$?
+		test $ret -eq 3 && usleep $uwait || break
+	done
+	return $ret
+}
+
 get_ethtool_drv_info () {
 	test -n "$1" || return 1
 	local ethtool="/sbin/ethtool"
diff --git a/scripts/ifup b/scripts/ifup
index 409a925..942c945 100755
--- a/scripts/ifup
+++ b/scripts/ifup
@@ -956,11 +956,8 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 			;;
 			ifstatus)
 				if is_iface_up $INTERFACE ; then
-					message_if_not_run_from_rc "$INTERFACE is up"
+					message "`printf "    %-9s is up" "$INTERFACE"`"
 					message_if_not_run_from_rc "$(ip addr show $INTERFACE)"
-					while read a b c d e f g h i; do
-						message "`printf "    %-9s IP address: %s" "$i" "$d"`"
-					done < <(ip -o -4 addr show $INTERFACE)
 					ifstatus-route $CONFIG $INTERFACE ${OPTIONS:+-o $OPTIONS}
 					retcode=$R_SUCCESS
 				else
@@ -1119,7 +1116,34 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 						ADDRCOUNT=$(($ADDRCOUNT + 1))
 					done
 				fi
+
 				ifup-route $CONFIG $INTERFACE ${OPTIONS:+-o $OPTIONS}
+
+				#
+				# OK, everything is set up here .. lets check the state
+				#
+
+				# - link
+				link_ready_wait "$INTERFACE" "${LINK_READY_WAIT:-$((WAIT_FOR_INTERFACES/2))}"
+				link_ret=$?
+				if [ "$retcode" = "$R_SUCCESS" ] ; then
+					# do not override codes when already set (e.g. $R_DHCP_BG)
+					case "$link_ret" in
+					1|2|3) retcode=$R_NOTRUNNING ;;
+					esac
+				fi
+
+				# - dad
+				if [ "$retcode" = "$R_SUCCESS" -a -d /proc/sys/net/ipv6 ] ; then
+					IPV6_DAD_WAIT=${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/5))}
+					ipv6_addr_dad_wait "$INTERFACE" "$IPV6_DAD_WAIT"
+					dad_ret=$?
+					case $dad_ret in
+					1|2) retcode=$R_NOTRUNNING ;;
+					3)   retcode=$R_DHCP_BG    ;;
+					esac
+				fi
+
 				;;
 			ifdown)
 				case "$BOOTPROTO" in
@@ -1141,13 +1165,55 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 				;;
 			ifstatus)
 				if is_iface_up $INTERFACE ; then
-					message_if_not_run_from_rc "$INTERFACE is up"
 					message_if_not_run_from_rc "$(ip addr show $INTERFACE)"
-					while read a b c d e f g h i; do
-						message "`printf "    %-9s IP address: %s" "$i" "$d"`"
-					done < <(ip -o -4 addr show $INTERFACE)
+					if [ "$RUN_FROM_RC" = "yes" ]; then
+						while read a b c d e f g h i; do
+							message "`printf "    %-9s IP address: %s" "$i" "$d"`"
+						done < <(ip -o -4 addr show $INTERFACE)
+						while read a b c d e f g h i; do
+							test "$f" = "global" || continue
+							message "`printf "    %-9s IP address: %s" "$b" "$d"`"
+						done < <(ip -o -6 addr show $INTERFACE)
+					fi
+
 					ifstatus-route $CONFIG $INTERFACE ${OPTIONS:+-o $OPTIONS}
+
 					retcode=$R_SUCCESS
+					dad_ret=0
+					link_ret=0
+
+					# Check the link
+					if [ -n "$LINK_READY_WAIT" -a $((LINK_READY_WAIT)) -gt 0 ] ; then
+						# check the link
+						link_ready_check "$INTERFACE" || link_ret=$?
+						case $link_ret in
+						1|2|3) retcode=$R_NOTRUNNING ;;
+						esac
+					fi
+
+					# Check ipv6 dad
+					if [ "$retcode" = "$R_SUCCESS" -a -d /proc/sys/net/ipv6 ] ; then
+						IPV6_DAD_WAIT=${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/5))}
+						if [ $((IPV6_DAD_WAIT)) -gt 0 ] ; then
+							ipv6_addr_dad_check "$INTERFACE"
+							dad_ret=$?
+						fi
+					fi
+
+					# OK, now show the results
+					case $link_ret in
+					0)
+					   # in link problem cases, IPv6 dad status is not yet interesting
+					   msg="is up"
+					   case $dad_ret in
+					   2) msg="is up, but ipv6 duplicate address check failed";;
+					   3) msg="is up, but has tentative ipv6 address";;
+					   esac
+					   message "`printf "    %-9s $msg" "$INTERFACE"`" ;;
+					1) message "`printf "    %-9s is not up" "$INTERFACE"`" ;;
+					2) message "`printf "    %-9s is dormant" "$INTERFACE"`" ;;
+					3) message "`printf "    %-9s has no carrier" "$INTERFACE"`" ;;
+					esac
 				else
 					# message_if_not_run_from_rc "$INTERFACE is down"
 					message "`printf "    %-9s is down" $INTERFACE`"
-- 
1.7.3.4


From a5f3ea9c2a4d01e84c503ca9334e3b4d1de7a46f Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Mon, 26 Sep 2011 11:33:20 +0200
Subject: [PATCH 2/4] Fixed wait for ipv6 duplicate address detection

Improved to not wait for link ready by default, because this breaks
the status of several interfaces (e.g. host-only bridges) and check
the ipv6 duplicate address detection only. IPv6 dad starts when the
link becomes up & ready, so this includes the link ready status.
The link ready check can be enabled on a per interface basis.
Fixed to not wait for each single interface separately in ifup, but
to wait for all together in /etc/init.d/network instead (bnc#697929).

Signed-off-by: Marius Tomaschewski <mt@suse.com>
---
 config/ifcfg.template           |   22 +++++++
 config/sysconfig.config-network |   15 +++--
 scripts/functions               |   43 ++++++++------
 scripts/ifup                    |  121 +++++++++++++++++++++++++++------------
 scripts/network                 |   81 +++++++++++++++++++++-----
 5 files changed, 206 insertions(+), 76 deletions(-)

diff --git a/config/ifcfg.template b/config/ifcfg.template
index 2ad0e70..4cbbb3e 100644
--- a/config/ifcfg.template
+++ b/config/ifcfg.template
@@ -167,6 +167,28 @@ LLADDR=
 #
 LINK_OPTIONS=
 
+## Type:        integer
+## Default:     0
+#
+# The number of seconds to wait for link to become useable / ready.
+# Default is 0, causing to not wait for a ready link (0), because link
+# detection can't be enabled in all cases (e.g. bridges without ports).
+# Please use per interface settings to enable it.
+#
+LINK_READY_WAIT=
+
+## Type:        integer
+## Default:     ""
+#
+# The number of seconds to wait for the end of IPv6 duplicate address
+# detection in ifup.
+# Default is to use WAIT_FOR_INTERFACES/2 seconds in normal ifup runs.
+# When ifup is called by /etc/init.d/network at boot time, the check
+# is done, but /etc/init.d/network waits WAIT_FOR_INTERFACES seconds
+# for all interfaces togerther. Set to 0 to disable it.
+#
+IPV6_DAD_WAIT=
+
 ## Type:    string
 ## Default: ""
 #
diff --git a/config/sysconfig.config-network b/config/sysconfig.config-network
index de045f8..e90bcfa 100644
--- a/config/sysconfig.config-network
+++ b/config/sysconfig.config-network
@@ -144,19 +144,24 @@ MANDATORY_DEVICES=""
 WAIT_FOR_INTERFACES="30"
 
 ## Type:        integer
-## Default:     ""
+## Default:     0
 #
 # The number of seconds to wait for link to become useable / ready.
-# Default is to use WAIT_FOR_INTERFACES/2 seconds. Set to 0 to disable.
+# Default is 0, causing to not wait for a ready link (0), because link
+# detection can't be enabled in all cases (e.g. bridges without ports).
+# Please use per interface settings to enable it.
 #
-LINK_READY_WAIT=""
+LINK_READY_WAIT=0
 
 ## Type:        integer
 ## Default:     ""
 #
 # The number of seconds to wait for the end of IPv6 duplicate address
-# detection. Default is to use WAIT_FOR_INTERFACES/5 seconds. Set to
-# 0 to disable.
+# detection in ifup.
+# Default is to use WAIT_FOR_INTERFACES/2 seconds in normal ifup runs.
+# When ifup is called by /etc/init.d/network at boot time, the check
+# is done, but /etc/init.d/network waits WAIT_FOR_INTERFACES seconds
+# for all interfaces togerther. Set to 0 to disable it.
 #
 IPV6_DAD_WAIT=""
 
diff --git a/scripts/functions b/scripts/functions
index c1f1e9c..a098f4a 100644
--- a/scripts/functions
+++ b/scripts/functions
@@ -139,19 +139,6 @@ link_ready_check () {
 	return 0
 }
 
-link_ready_wait () {
-	local iface=$1
-	local wsecs=${2:-0}
-	local uwait=25000
-	local loops=$(((wsecs * 100000) / $uwait))
-	local loop ret=0
-	for((loop=0; loop < $loops; loop++)) ; do
-		link_ready_check "$iface" ; ret=$?
-		test $ret -ne 0 && usleep $uwait || break
-	done
-	return $ret
-}
-
 ipv6_addr_dad_check()
 {
 	local iface="$1" word i
@@ -182,16 +169,34 @@ ipv6_addr_dad_check()
 	return $R_SUCCESS
 }
 
+link_ready_wait ()
+{
+	local iface=$1
+	local -i wsecs=${2:-0}
+	local -i uwait=25000
+	local -i loops=$(((wsecs * 100000) / $uwait))
+	local -i loop=0 ret=0
+
+	link_ready_check "$iface" ; ret=$?
+	while ((ret != 0 && loop++ < loops)) ; do
+		usleep $uwait
+		link_ready_check "$iface" ; ret=$?
+	done
+	return $ret
+}
+
 ipv6_addr_dad_wait()
 {
 	local iface=$1
-	local wsecs=${2:-0}
-	local uwait=25000
-	local loops=$(((wsecs * 100000) / $uwait))
-	local loop ret=0
-	for((loop=0; loop < $loops; loop++)) ; do
+	local -i wsecs=${2:-0}
+	local -i uwait=25000
+	local -i loops=$(((wsecs * 100000) / $uwait))
+	local -i loop=0 ret=0
+
+	ipv6_addr_dad_check "$iface" ; ret=$?
+	while ((ret == 3 && loop++ < loops)) ; do
+		usleep $uwait
 		ipv6_addr_dad_check "$iface" ; ret=$?
-		test $ret -eq 3 && usleep $uwait || break
 	done
 	return $ret
 }
diff --git a/scripts/ifup b/scripts/ifup
index 942c945..8c91ee3 100755
--- a/scripts/ifup
+++ b/scripts/ifup
@@ -96,6 +96,7 @@ test "$1" = "-o" && shift
 OPTIONS=$@
 MODE=manual
 HOTPLUG=no
+BOOTING=no
 CONTROL_IFPLUGD=yes # Start/Stop ifplugd?
 # Don't log messages from ifstatus in syslog by default (Bug 261350). This
 # overwrites the config variable /etc/sysconfig/network/config:USE_SYSLOG
@@ -103,7 +104,7 @@ export DONT_USE_SYSLOG=no
 test "$SCRIPTNAME" == ifstatus && DONT_USE_SYSLOG=yes
 while [ $# -gt 0 ]; do
 	case $1 in
-		boot|onboot) MODE=auto ;;
+		boot|onboot) MODE=auto ; BOOTING=yes ;;
 		auto)        MODE=auto ;;
 		hotplug)     MODE=auto
 		             HOTPLUG=yes ;;
@@ -423,7 +424,7 @@ setexitstate () {
 			esac
 			commit_cached_config_data $INTERFACE
 			commit_cached_config_data $INTERFACE PFX=ifup-
-			;;
+		;;
 		ifdown)
 			test "$HOTPLUG" = yes && RET_STATE=removed
 			test "$RUN_FROM_RC" = yes && RET_STATE=removed
@@ -447,7 +448,7 @@ setexitstate () {
 			commit_cached_config_data $INTERFACE
 			delete_from_cached_config_data '*' '' $INTERFACE PFX=ifup-
 			commit_cached_config_data $INTERFACE PFX=ifup-
-			;;
+		;;
 	esac
 }
 
@@ -501,6 +502,11 @@ DEVNAME=
 if [ -n "$VENDORID$PRODUCTID" -a "$BUSNAME" = pci -a -x /sbin/lspci ] ; then
 	DEVNAME=`lspci -d $VENDORID:$PRODUCTID 2>/dev/null | sed -n 1p`
 	DEVNAME=${DEVNAME#*: }
+	if [ "$RUN_FROM_RC" = yes ] ; then
+		DEVNAME=${DEVNAME%%[(\[]*}
+		DEVNAME=${DEVNAME:0:45}
+		NAME=${NAME:0:45}
+	fi
 elif [ "$BUSNAME" = pcmcia ] ; then
 	DEVNAME=`cat /sys/class/net/$INTERFACE/device/prod_id* 2>/dev/null`
 fi
@@ -1057,9 +1063,6 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 								# else
 								#	message_n "`printf "IP/Netmask: %s / %s  " $IPADDR $NETMASK`"
 								fi
-								if [ "$INTERFACETYPE" == bond ] ; then
-									message_n " as bonding master"
-								fi
 								message " "
 								;;
 							esac
@@ -1120,28 +1123,57 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 				ifup-route $CONFIG $INTERFACE ${OPTIONS:+-o $OPTIONS}
 
 				#
-				# OK, everything is set up here .. lets check the state
+				# OK, all setup done ... check the state now
+				#
+				# Do not override codes when already set (e.g. $R_DHCP_BG);
+				# it is the final action to check the link / dad status.
+				#
+				# When called from rcnetwork, do not wait as rcnetwork does.
 				#
+				dad_ret=0
+				link_ret=0
 
-				# - link
-				link_ready_wait "$INTERFACE" "${LINK_READY_WAIT:-$((WAIT_FOR_INTERFACES/2))}"
-				link_ret=$?
+				# - check the link (carrier, ...)
+				#   per interface setting, disabled by default
 				if [ "$retcode" = "$R_SUCCESS" ] ; then
-					# do not override codes when already set (e.g. $R_DHCP_BG)
-					case "$link_ret" in
-					1|2|3) retcode=$R_NOTRUNNING ;;
-					esac
+					if [ $((LINK_READY_WAIT)) -gt 0 ] ; then
+						if [ "$BOOTING" = yes -a "$RUN_FROM_RC" = yes ] ; then
+							link_ready_check "$INTERFACE"
+							link_ret=$?
+							test "$link_ret" && retcode=$R_DHCP_BG
+						else
+							link_ready_wait "$INTERFACE" "${LINK_READY_WAIT}"
+							link_ret=$?
+							test "$link_ret" && retcode=$R_NOTRUNNING
+						fi
+					fi
 				fi
 
-				# - dad
-				if [ "$retcode" = "$R_SUCCESS" -a -d /proc/sys/net/ipv6 ] ; then
-					IPV6_DAD_WAIT=${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/5))}
-					ipv6_addr_dad_wait "$INTERFACE" "$IPV6_DAD_WAIT"
-					dad_ret=$?
-					case $dad_ret in
-					1|2) retcode=$R_NOTRUNNING ;;
-					3)   retcode=$R_DHCP_BG    ;;
-					esac
+				# - check ipv6 dad
+				#   global (and per interface) setting, enabled by default
+				#   when the link isn't ready yet, the addresses are marked tentative
+				#   dad starts when the link becomes ready and we wait until success
+				#   or dad failure.
+				if [ "$retcode" = "$R_SUCCESS" ] ; then
+					IPV6_DAD_WAIT=${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/2))}
+					if [ $((IPV6_DAD_WAIT)) -gt 0 ] ; then
+						if [ "$BOOTING" = yes -a "$RUN_FROM_RC" = yes ] ; then
+							ipv6_addr_dad_check "$INTERFACE"
+							dad_ret=$?
+						else
+							ipv6_addr_dad_wait "$INTERFACE" "${IPV6_DAD_WAIT}"
+							dad_ret=$?
+						fi
+						case $dad_ret in
+							1|2) retcode=$R_NOTRUNNING ;;
+							3)   retcode=$R_DHCP_BG    ;;
+						esac
+					fi
+				fi
+
+				# inform ifstatus to update status connecting flag
+				if [ $retcode -eq $R_DHCP_BG -a \( $link_ret -ne 0 -o $dad_ret -ne 0 \) ] ; then
+					write_cached_config_data verify status $INTERFACE
 				fi
 
 				;;
@@ -1178,25 +1210,31 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 
 					ifstatus-route $CONFIG $INTERFACE ${OPTIONS:+-o $OPTIONS}
 
-					retcode=$R_SUCCESS
 					dad_ret=0
 					link_ret=0
+					retcode=$R_SUCCESS
 
-					# Check the link
-					if [ -n "$LINK_READY_WAIT" -a $((LINK_READY_WAIT)) -gt 0 ] ; then
-						# check the link
-						link_ready_check "$INTERFACE" || link_ret=$?
-						case $link_ret in
-						1|2|3) retcode=$R_NOTRUNNING ;;
-						esac
+					# - check the link
+					if [ $((LINK_READY_WAIT)) -gt 0 ] ; then
+						link_ready_check "$INTERFACE"
+						link_ret=$?
+						if [ "$BOOTING" = yes -a "$RUN_FROM_RC" = yes ] ; then
+							test "$link_ret" && retcode=$R_DHCP_BG
+						else
+							test "$link_ret" && retcode=$R_NOTRUNNING
+						fi
 					fi
 
-					# Check ipv6 dad
-					if [ "$retcode" = "$R_SUCCESS" -a -d /proc/sys/net/ipv6 ] ; then
-						IPV6_DAD_WAIT=${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/5))}
-						if [ $((IPV6_DAD_WAIT)) -gt 0 ] ; then
+					# - check ipv6 dad
+					if [ "$retcode" = "$R_SUCCESS" ] ; then
+						IPV6_DAD_WAIT=$((${IPV6_DAD_WAIT:-$((WAIT_FOR_INTERFACES/2))}))
+						if [ $((IPV6_DAD_WAIT)) -ge 0 ] ; then
 							ipv6_addr_dad_check "$INTERFACE"
 							dad_ret=$?
+							case $dad_ret in
+								1|2) retcode=$R_NOTRUNNING ;;
+								3)   retcode=$R_DHCP_BG    ;;
+							esac
 						fi
 					fi
 
@@ -1214,12 +1252,21 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 					2) message "`printf "    %-9s is dormant" "$INTERFACE"`" ;;
 					3) message "`printf "    %-9s has no carrier" "$INTERFACE"`" ;;
 					esac
+
+					if [ "$retcode" = "$R_SUCCESS" ] ; then
+						v=`read_cached_config_data verify $INTERFACE`
+						s=`read_cached_config_data status $INTERFACE`
+						if test "$v" = "status" -a "$s" = "connecting" ; then
+							write_cached_config_data status connected $INTERFACE
+							commit_cached_config_data $INTERFACE
+						fi
+					fi
 				else
 					# message_if_not_run_from_rc "$INTERFACE is down"
 					message "`printf "    %-9s is down" $INTERFACE`"
 					retcode=$R_NOTRUNNING
 					case "$STARTMODE" in
-					manual|off) retcode=$R_INACTIVE ;;
+						manual|off) retcode=$R_INACTIVE ;;
 					esac
 				fi
 				;;
@@ -1245,7 +1292,7 @@ if [ "$DHCP" != yes ] ; then
 		test "$CHECK" = yes -a $ret != 0 && retcode=$ret
 		DEP_IFACES=`get_depending_ifaces $INTERFACE`
 		if [ "$?" = 0 -a "$NODEPS" != yes ] ; then
-			message "`printf "    %-9s is still used from interfaces %s" \
+			message "`printf "    %-9s is used from interfaces %s" \
 			                 $INTERFACE "$DEP_IFACES"`"
 			#for DI in $DEP_IFACES; do
 			#  ifstatus $DI -o $OPTIONS
diff --git a/scripts/network b/scripts/network
index fa397a0..b05c349 100755
--- a/scripts/network
+++ b/scripts/network
@@ -673,8 +673,7 @@ status() {
 	for IFACE in $@; do
 		$FAKE /sbin/ifstatus $CONFIG $IFACE -o rc $CHECK $MODE
 		RET=$?
-		debug && printf "    %-9s returned %s\n" $IFACE $RET || \
-		         printf "    %-9s\n" $IFACE
+		debug && printf "    %-9s returned %s\n" $IFACE $RET
 		case $RET in
 			$R_SUCCESS|$R_BUSY)
 				# : $((R++))
@@ -744,8 +743,7 @@ case "$ACTION" in
 			done
 			$FAKE ifup $CONFIG $IFACE -o rc $MODE
 			RET=$?
-			debug && printf "    %-9s returned %s\n" $IFACE $RET || \
-			         printf "    %-9s\n" $IFACE
+			debug && printf "    %-9s returned %s\n" $IFACE $RET
 			case "$RET" in
 	 			$R_SUCCESS)
 	 				SUCCESS_IFACES="$SUCCESS_IFACES $IFACE"
@@ -830,7 +828,7 @@ case "$ACTION" in
 
 			debug "Time to wait: $((WAIT_FOR_INTERFACES - TTWAIT))"
 			if [ "$NEWLINE" != yes ] ; then
-				echo "Waiting for mandatory devices: $MANDATORY_DEVICES"
+				echo "Waiting for mandatory devices: ${MANDATORY_DEVICES//__NSC__/}"
 			fi
 			echo -n "$((WAIT_FOR_INTERFACES - TTWAIT)) "
 			NEWLINE=yes
@@ -860,7 +858,7 @@ case "$ACTION" in
 		debug SUCCESS_IFACES=$SUCCESS_IFACES
 		debug MANDATORY_DEVICES=$MANDATORY_DEVICES
 		debug FAILED=$FAILED
-
+		debug TTWAIT=$TTWAIT
 
 		if [ -z "$INTERFACE" ] ; then
 			for IFACE in $VIRTUAL_IFACES ; do
@@ -869,8 +867,7 @@ case "$ACTION" in
 				done
 				$FAKE ifup $CONFIG $IFACE -o rc $MODE
 				RET=$?
-				debug && printf "    %-9s returned %s\n" $IFACE $RET || \
-				         printf "    %-9s\n" $IFACE
+				debug && printf "    %-9s returned %s\n" $IFACE $RET
 				case "$RET" in
 		 			$R_SUCCESS)
 		 				SUCCESS_IFACES="$SUCCESS_IFACES $IFACE"
@@ -885,7 +882,7 @@ case "$ACTION" in
 					$R_NOCONFIG)
 						rc_failed 6
 						rc_status -v1
-						: $((FAILED++))
+						# : $((FAILED++))
 						;;
 		 			$R_NOTCONFIGURED|$R_INACTIVE)
 		 				SUCCESS_IFACES="$SUCCESS_IFACES $IFACE"
@@ -895,13 +892,69 @@ case "$ACTION" in
 		 			*)
 		 				rc_failed 7
 		 				rc_status -v1
-						: $((FAILED++))
+						# : $((FAILED++))
 		 				;;
 				esac
 				rc_reset
 			done
-		fi
 
+			LINE=""
+			NEWLINE=no
+			while true; do
+				debug ... still waiting for virtual devices:
+				debug SUCCESS_IFACES=$SUCCESS_IFACES
+				debug VIRTUAL_IFACES=$VIRTUAL_IFACES
+
+				TMP=$VIRTUAL_IFACES
+				VIRTUAL_IFACES=
+				for IFACE in $TMP ; do
+					for S in $SUCCESS_IFACES; do
+						test "$IFACE" = "$S" && continue 2
+					done
+					IFACE="`type_filter $IFACE`"
+					test -z "$IFACE" && continue
+					status -m $IFACE &>/dev/null
+					RET=$?
+					if [ $RET = 0 ] ; then
+						SUCCESS_IFACES="$SUCCESS_IFACES $IFACE"
+						if [ "$NEWLINE" = yes ] ; then
+							echo
+							NEWLINE=no
+						fi
+						status $IFACE
+						continue
+					fi
+					VIRTUAL_IFACES="$VIRTUAL_IFACES $IFACE"
+				done
+	
+				IFS=. read a b < /proc/uptime
+				TTWAIT2=$((a - (TTWAIT + `cat $NETWORK_RUNFILE`)))
+				test $TTWAIT2 -gt $((WAIT_FOR_INTERFACES)) \
+					-o -z "$VIRTUAL_IFACES" && break
+
+				debug "Time to wait: $((WAIT_FOR_INTERFACES - TTWAIT2))"
+				if [ "$NEWLINE" != yes ] ; then
+					echo "Waiting for virtual interfaces: $VIRTUAL_IFACES"
+				fi
+				echo -n "$((WAIT_FOR_INTERFACES - TTWAIT2)) "
+				NEWLINE=yes
+				sleep 1
+			done
+
+			if [ "$NEWLINE" = yes ] ; then
+				echo
+			fi
+
+			for IFACE in $VIRTUAL_IFACES; do
+				if [ -d /sys/class/net/$IFACE ] ; then
+					status -m $IFACE && continue
+					printf "    %-9s interface is not ready until now\n" $IFACE
+				fi
+				rc_failed
+				rc_status -v1
+				: $((FAILED++))
+			done
+		fi
 
 		rc_reset
 		if [ -z "$INTERFACE" ] ; then
@@ -939,8 +992,7 @@ case "$ACTION" in
 			# printf "    %-9s " $IFACE
 			$FAKE ifdown $CONFIG $IFACE -o rc $MODE
 			RET=$?
-			debug && printf "    %-9s returned %s\n" $IFACE $RET || \
-			         printf "    %-9s\n" $IFACE
+			debug && printf "    %-9s returned %s\n" $IFACE $RET
 			rc_failed $RET
 			case "$RET" in
 				$R_NODEV|$R_NOTCONFIGURED|$R_INACTIVE)
@@ -987,8 +1039,7 @@ case "$ACTION" in
 			fi
 			$FAKE ifdown $CONFIG $IFACE -o rc $MODE
 			RET=$?
-			debug && printf "    %-9s returned %s\n" $IFACE $RET || \
-			         printf "    %-9s\n" $IFACE
+			debug && printf "    %-9s returned %s\n" $IFACE $RET
 			rc_failed $RET
 			case "$RET" in
 				$R_NODEV|$R_NOTCONFIGURED|$R_INACTIVE)
-- 
1.7.3.4


From 69e318dbdded2de5f3e387ab6dbdd08883c1bdc5 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Mon, 26 Sep 2011 14:32:25 +0200
Subject: [PATCH 3/4] Fixed inverted link ready return value test


Signed-off-by: Marius Tomaschewski <mt@suse.com>
---
 scripts/ifup |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/ifup b/scripts/ifup
index 8c91ee3..4d3e594 100755
--- a/scripts/ifup
+++ b/scripts/ifup
@@ -1140,11 +1140,11 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 						if [ "$BOOTING" = yes -a "$RUN_FROM_RC" = yes ] ; then
 							link_ready_check "$INTERFACE"
 							link_ret=$?
-							test "$link_ret" && retcode=$R_DHCP_BG
+							test "$link_ret" -eq 0 || retcode=$R_DHCP_BG
 						else
 							link_ready_wait "$INTERFACE" "${LINK_READY_WAIT}"
 							link_ret=$?
-							test "$link_ret" && retcode=$R_NOTRUNNING
+							test "$link_ret" -eq 0 || retcode=$R_NOTRUNNING
 						fi
 					fi
 				fi
@@ -1219,9 +1219,9 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 						link_ready_check "$INTERFACE"
 						link_ret=$?
 						if [ "$BOOTING" = yes -a "$RUN_FROM_RC" = yes ] ; then
-							test "$link_ret" && retcode=$R_DHCP_BG
+							test "$link_ret" -eq 0 || retcode=$R_DHCP_BG
 						else
-							test "$link_ret" && retcode=$R_NOTRUNNING
+							test "$link_ret" -eq 0 || retcode=$R_NOTRUNNING
 						fi
 					fi
 
-- 
1.7.3.4


From f6d6bd9ccf89b6e016d890c6fc6834740b287d53 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Tue, 27 Sep 2011 13:28:49 +0200
Subject: [PATCH 4/4] Cleanup verify flag after status update


Signed-off-by: Marius Tomaschewski <mt@suse.com>
---
 scripts/ifup |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/scripts/ifup b/scripts/ifup
index 4d3e594..343b482 100755
--- a/scripts/ifup
+++ b/scripts/ifup
@@ -1256,8 +1256,11 @@ case "$BOOTPROTO$SKIP_MAIN_PART" in
 					if [ "$retcode" = "$R_SUCCESS" ] ; then
 						v=`read_cached_config_data verify $INTERFACE`
 						s=`read_cached_config_data status $INTERFACE`
-						if test "$v" = "status" -a "$s" = "connecting" ; then
-							write_cached_config_data status connected $INTERFACE
+						if test "$v" = "status" ; then
+							if test "$s" = "connecting" ; then
+								write_cached_config_data status connected $INTERFACE
+							fi
+							delete_from_cached_config_data verify ""  $INTERFACE
 							commit_cached_config_data $INTERFACE
 						fi
 					fi
-- 
1.7.3.4

