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').
This commit is contained in:
parent
baf4f1f082
commit
2cc6c69d05
@ -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"
|
||||
|
@ -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\" \
|
||||
|
@ -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-
|
||||
|
Loading…
Reference in New Issue
Block a user