Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jan 2014 07:42:32 +0000 (UTC)
From:      Devin Teske <dteske@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r260676 - in stable/10/usr.sbin/bsdconfig: networking networking/share share
Message-ID:  <201401150742.s0F7gWpR016429@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dteske
Date: Wed Jan 15 07:42:31 2014
New Revision: 260676
URL: http://svnweb.freebsd.org/changeset/base/260676

Log:
  MFC r258458:
  Improve network device scanning in the netdev module. First, make it use the
  `device.subr' framework (improving performane and reducing sub-shells). Next
  improve the `device.subr' framework itself. Make use of the `flags' device
  struct member for network interfaces to indicate if an interface is Active,
  Wired Ethernet, or 802.11 Wireless. Functions have been added to make checks
  against the `flags' bit-field quick and efficient. Last, add function for
  rescanning the network to update the device registers. Remove an unnecessary
  local (ifn) while we're here (use already provided local `if').

Modified:
  stable/10/usr.sbin/bsdconfig/networking/devices
  stable/10/usr.sbin/bsdconfig/networking/share/device.subr
  stable/10/usr.sbin/bsdconfig/share/device.subr
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/bsdconfig/networking/devices
==============================================================================
--- stable/10/usr.sbin/bsdconfig/networking/devices	Wed Jan 15 07:36:34 2014	(r260675)
+++ stable/10/usr.sbin/bsdconfig/networking/devices	Wed Jan 15 07:42:31 2014	(r260676)
@@ -28,6 +28,12 @@
 #
 ############################################################ INCLUDES
 
+# Prevent device.subr (included indirectly) from auto scanning; this will be
+# performed indirectly later via f_dialog_menu_netdev() -- but only after we've
+# successfully completed f_mustberoot_init().
+#
+DEVICE_SELF_SCAN_ALL=NO
+
 BSDCFG_SHARE="/usr/share/bsdconfig"
 . $BSDCFG_SHARE/common.subr || exit 1
 f_dprintf "%s: loading includes..." "$0"

Modified: stable/10/usr.sbin/bsdconfig/networking/share/device.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/networking/share/device.subr	Wed Jan 15 07:36:34 2014	(r260675)
+++ stable/10/usr.sbin/bsdconfig/networking/share/device.subr	Wed Jan 15 07:42:31 2014	(r260676)
@@ -74,8 +74,10 @@ f_dialog_menu_netdev()
 	#
 	# Get list of usable network interfaces
 	#
-	local if iflist= # Calculated below
-	for if in $( ifconfig -l ); do
+	local devs if iflist= # Calculated below
+	f_device_rescan_network
+	f_device_find "" $DEVICE_TYPE_NETWORK devs
+	for if in $devs; do
 		# Skip unsavory interfaces
 		case "$if" in
 		lo[0-9]*|ppp[0-9]*|sl[0-9]*|faith[0-9]*) continue ;;
@@ -91,9 +93,8 @@ f_dialog_menu_netdev()
 	if [ "$DIALOG_MENU_NETDEV_KICK_INTERFACES" ]; then
 		DIALOG_MENU_NETDEV_KICK_INTERFACES=
 
-		local ifn
-		for ifn in $iflist; do
-			f_quietly ifconfig $ifn up
+		for if in $iflist; do
+			f_quietly ifconfig $if up
 		done
 
 		if [ "$DIALOG_MENU_NETDEV_SLEEP_AFTER_KICK" ]; then
@@ -107,13 +108,14 @@ f_dialog_menu_netdev()
 	# to the right of the device name.
 	#
 	menu_list=$(
-		for ifn in $iflist; do
-			active=$( ifconfig $ifn 2> /dev/null | awk '
-			($1 == "status:") {
-				if ($2 == "active") { print 1; exit }
-			}' )
-			printf "'%s%s' '%s'\n" \
-				$ifn "${active:+*}" "$( f_device_desc $ifn )"
+		for if in $iflist; do
+			f_device_desc $if $DEVICE_TYPE_NETWORK desc
+			f_shell_escape "$desc" desc
+			if f_device_is_active $if; then
+				printf "'%s\*' '%s'\n" $if "$desc"
+			else
+				printf "'%s' '%s'\n" $if "$desc"
+			fi
 		done
 	)
 	if [ ! "$menu_list" ]; then
@@ -121,21 +123,14 @@ f_dialog_menu_netdev()
 		return $DIALOG_CANCEL
 	fi
 
-	#
 	# Maybe the default item was marked as active
-	#
-	if [ "$defaultitem" ]; then
-		ifconfig "$defaultitem" 2> /dev/null |
-			awk '($1 == "status:" && $2 == "active"){exit 1}' ||
-			defaultitem="$defaultitem*"
-	fi
-
-	local hline="$hline_arrows_tab_enter"
+	f_device_is_active "$defaultitem" && defaultitem="$defaultitem*"
 
 	#
 	# Ask user to select an interface
 	#
 	local prompt="$msg_select_network_interface"
+	local hline="$hline_arrows_tab_enter"
 	local height width rows
 	eval f_dialog_menu_size height width rows \
 	                        \"\$DIALOG_TITLE\"     \

Modified: stable/10/usr.sbin/bsdconfig/share/device.subr
==============================================================================
--- stable/10/usr.sbin/bsdconfig/share/device.subr	Wed Jan 15 07:36:34 2014	(r260675)
+++ stable/10/usr.sbin/bsdconfig/share/device.subr	Wed Jan 15 07:42:31 2014	(r260676)
@@ -76,6 +76,11 @@ setvar DEVICE_TYPE_ANY		11
 setvar DEVICE_TYPE_HTTP_PROXY	12
 setvar DEVICE_TYPE_HTTP		13
 
+# Network devices have the following flags available
+setvar IF_ETHERNET	1
+setvar IF_WIRELESS	2
+setvar IF_ACTIVE	4
+
 #
 # Default behavior is to call f_device_get_all() automatically when loaded.
 #
@@ -175,6 +180,33 @@ f_device_reset()
 	DEVICES=
 }
 
+# f_device_reset_network
+#
+# Reset the registered network device chain.
+#
+f_device_reset_network()
+{
+	local dev type private pruned_list=
+	for dev in $DEVICES; do
+		device_$dev get type type
+		if [ "$type" != "$DEVICE_TYPE_NETWORK" ]; then
+			pruned_list="$pruned_list $dev"
+			continue
+		fi
+
+		#
+		# Leave the device up (don't call shutdown routine)
+		#
+
+		# Network devices may have DEVICE_INFO private member
+		device_$dev get private private
+		[ "$private" ] && f_struct_free "$private"
+
+		f_struct_free device_$dev
+	done
+	DEVICES="${pruned_list# }"
+}
+
 # f_device_get_all
 #
 # Get all device information for devices we have attached.
@@ -187,20 +219,7 @@ f_device_get_all()
 	f_dialog_info "$msg_probing_devices_please_wait_this_can_take_a_while"
 
 	# First go for the network interfaces
-	for devname in $( ifconfig -l ); do
-		# Eliminate network devices that don't make sense
-		case "$devname" in
-		lo*) continue ;;
-		esac
-
-		# Try and find its description
-		f_device_desc "$devname" $DEVICE_TYPE_NETWORK desc
-
-		f_dprintf "Found a network device named %s" "$devname"
-		f_device_register $devname \
-			"$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
-			f_media_init_network "" f_media_shutdown_network "" -1
-	done
+	f_device_get_all_network
 
 	# Next, try to find all the types of devices one might use
 	# as a media source for content
@@ -378,6 +397,48 @@ f_device_get_all()
 	done # disks
 }
 
+# f_device_get_all_network
+#
+# Get all network device information for attached network devices.
+#
+f_device_get_all_network()
+{
+	local devname desc flags
+	for devname in $( ifconfig -l ); do
+		# Eliminate network devices that don't make sense
+		case "$devname" in
+		lo*) continue ;;
+		esac
+
+		# Try and find its description
+		f_device_desc "$devname" $DEVICE_TYPE_NETWORK desc
+
+		f_dprintf "Found a network device named %s" "$devname"
+		f_device_register $devname \
+			"$desc" "$devname" $DEVICE_TYPE_NETWORK 1 \
+			f_media_init_network "" f_media_shutdown_network "" -1
+
+		# Set flags based on media and status
+		flags=0
+		eval "$( ifconfig $devname 2> /dev/null | awk -v var=flags '
+		function _or(var, mask) {
+			printf "%s=$(( $%s | $%s ))\n", var, var, mask
+		}
+		BEGIN { S = "[[:space:]]+" }
+		{
+			if (!match($0, "^" S "(media|status):" S)) next
+			value = substr($0, RLENGTH + 1)
+			if ($1 == "media:") {
+				if (value ~ /Ethernet/) _or(var, "IF_ETHERNET")
+				if (value ~ /802\.11/) _or(var, "IF_WIRELESS")
+			} else if ($1 == "status:") {
+				if (value ~ /^active/) _or(var, "IF_ACTIVE")
+			}
+		}' )"
+		device_$devname set flags $flags
+	done
+}
+
 # f_device_name_get $type $name type|desc|max [$var_to_set]
 #
 # Fetch the device type (type), description (desc), or maximum number of
@@ -571,6 +632,72 @@ f_device_desc()
 	return $FAILURE
 }
 
+# f_device_is_ethernet $device
+#
+# Returns true if $device is a wired Ethernet network interface. Otherwise
+# returns false. Example wired interfaces include: fxp0 em0 bge0 rl0 etc.
+#
+f_device_is_ethernet()
+{
+	local dev="$1" type flags
+
+	# Make sure we have an actual device by that name
+	f_struct "device_$dev" || return $FAILURE
+
+	# Make sure that the device is a network device
+	device_$dev get type type
+	[ "$type" = "$DEVICE_TYPE_NETWORK" ] || return $FAILURE
+
+	# Make sure that the media flags indicate that it is Ethernet
+	device_$dev get flags flags
+	[ $(( ${flags:-0} & $IF_ETHERNET )) -eq $IF_ETHERNET ]
+}
+
+# f_device_is_wireless $device
+#
+# Returns true if $device is a Wireless network interface. Otherwise returns
+# false. Examples of wireless interfaces include: iwn0
+#
+f_device_is_wireless()
+{
+	local dev="$1" type flags
+
+	# Make sure we have an actual device by that name
+	f_struct "device_$dev" || return $FAILURE
+
+	# Make sure that the device is a network device
+	device_$dev get type type
+	[ "$type" = "$DEVICE_TYPE_NETWORK" ] || return $FAILURE
+
+	# Make sure that the media flags indicate that it is Ethernet
+	device_$dev get flags flags
+	[ $(( ${flags:-0} & $IF_WIRELESS )) -eq $IF_WIRELESS ]
+}
+
+# f_device_is_active $device
+#
+# Returns true if $device is active. Otherwise returns false. Currently this
+# only works for network interfaces.
+#
+f_device_is_active()
+{
+	local dev="$1" type flags=0
+
+	# Make sure we have an actual device by that name
+	f_struct "device_$dev" || return $FAILURE
+
+	device_$dev get type type
+	case "$type" in
+	$DEVICE_TYPE_NETWORK)
+		# Make sure that the media flags indicate that it is active
+		device_$dev get flags flags
+		[ $(( ${flags:-0} & $IF_ACTIVE )) -eq $IF_ACTIVE ]
+		;;
+	*)
+		return $FAILURE
+	esac
+}
+
 # f_device_rescan
 #
 # Rescan all devices, after closing previous set - convenience function.
@@ -581,6 +708,16 @@ f_device_rescan()
 	f_device_get_all
 }
 
+# f_device_rescan_network
+#
+# Rescan all network devices, after closing previous set - for convenience.
+#
+f_device_rescan_network()
+{
+	f_device_reset_network
+	f_device_get_all_network
+}
+
 # f_device_find $name [$type [$var_to_set]] 
 #
 # Find one or more registered devices by name, type, or both. Returns a space-



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401150742.s0F7gWpR016429>