From owner-svn-src-all@FreeBSD.ORG Wed Jan 15 07:42:32 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CAC2A75D; Wed, 15 Jan 2014 07:42:32 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id B4BF51445; Wed, 15 Jan 2014 07:42:32 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id s0F7gWQG016432; Wed, 15 Jan 2014 07:42:32 GMT (envelope-from dteske@svn.freebsd.org) Received: (from dteske@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id s0F7gWpR016429; Wed, 15 Jan 2014 07:42:32 GMT (envelope-from dteske@svn.freebsd.org) Message-Id: <201401150742.s0F7gWpR016429@svn.freebsd.org> From: Devin Teske Date: Wed, 15 Jan 2014 07:42:32 +0000 (UTC) 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 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jan 2014 07:42:32 -0000 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-