@ -19,6 +19,11 @@ iw() {
command iw $@ || logger -t mac80211 " Failed command: iw $@ "
}
NEWAPLIST =
OLDAPLIST =
NEWSPLIST =
OLDSPLIST =
drv_mac80211_init_device_config( ) {
hostapd_common_add_device_config
@ -58,7 +63,7 @@ drv_mac80211_init_iface_config() {
config_add_string 'macaddr:macaddr' ifname
config_add_boolean wds powersave
config_add_boolean wds powersave enable
config_add_int maxassoc
config_add_int max_listen_int
config_add_int dtim_period
@ -454,7 +459,7 @@ mac80211_iw_interface_add() {
mac80211_prepare_vif( ) {
json_select config
json_get_vars ifname mode ssid wds powersave macaddr
json_get_vars ifname mode ssid wds powersave macaddr enable
[ -n " $ifname " ] || ifname = " wlan ${ phy #phy } ${ if_idx : +- $if_idx } "
if_idx = $(( ${ if_idx :- 0 } + 1 ))
@ -490,8 +495,8 @@ mac80211_prepare_vif() {
mac80211_hostapd_setup_bss " $phy " " $ifname " " $macaddr " " $type " || return
NEWAPLIST = " ${ NEWAPLIST } $ifname "
[ -n " $hostapd_ctrl " ] || {
mac80211_iw_interface_add " $phy " " $ifname " __ap || return
hostapd_ctrl = " ${ hostapd_ctrl :- /var/run/hostapd/ $ifname } "
}
; ;
@ -503,7 +508,7 @@ mac80211_prepare_vif() {
; ;
sta)
local wdsflag =
staidx = " $(( $staidx + 1 )) "
[ " $enable " = 0 ] || staidx = " $(( $staidx + 1 )) "
[ " $wds " -gt 0 ] && wdsflag = "4addr on"
mac80211_iw_interface_add " $phy " " $ifname " managed " $wdsflag " || return
[ " $powersave " -gt 0 ] && powersave = "on" || powersave = "off"
@ -529,19 +534,62 @@ mac80211_prepare_vif() {
}
mac80211_setup_supplicant( ) {
local enable = $1
local add_sp = 0
local spobj = " $( ubus -S list | grep wpa_supplicant.${ ifname } ) "
wpa_supplicant_prepare_interface " $ifname " nl80211 || return 1
wpa_supplicant_prepare_interface " $ifname " nl80211 || {
iw dev " $ifname " del
return 1
}
if [ " $mode " = "sta" ] ; then
wpa_supplicant_add_network " $ifname "
else
wpa_supplicant_add_network " $ifname " " $freq " " $htmode " " $noscan "
fi
wpa_supplicant_run " $ifname " ${ hostapd_ctrl : +-H $hostapd_ctrl }
NEWSPLIST = " ${ NEWSPLIST } $ifname "
if [ " ${ NEWAPLIST %% * } " != " ${ OLDAPLIST %% * } " ] ; then
[ " $spobj " ] && ubus call wpa_supplicant.${ phy } config_del " {\"iface\":\" $ifname \"} "
add_sp = 1
fi
[ " $enable " = 0 ] && {
ubus call wpa_supplicant.${ phy } config_del " {\"iface\":\" $ifname \"} "
ip link set dev " $ifname " down
return 0
}
[ -z " $spobj " ] && add_sp = 1
if [ " $add_sp " = "1" ] ; then
wpa_supplicant_run " $ifname " " $hostapd_ctrl "
else
ubus call $spobj reload
fi
}
mac80211_setup_supplicant_noctl( ) {
wpa_supplicant_prepare_interface " $ifname " nl80211 || return 1
local enable = $1
local spobj = " $( ubus -S list | grep wpa_supplicant.${ ifname } ) "
wpa_supplicant_prepare_interface " $ifname " nl80211 || {
iw dev " $ifname " del
return 1
}
wpa_supplicant_add_network " $ifname " " $freq " " $htmode " " $noscan "
wpa_supplicant_run " $ifname "
NEWSPLIST = " ${ NEWSPLIST } $ifname "
[ " $enable " = 0 ] && {
ubus call wpa_supplicant.${ phy } config_del " {\"iface\":\" $ifname \"} "
ip link set dev " $ifname " down
return 0
}
if [ -z " $spobj " ] ; then
wpa_supplicant_run " $ifname "
else
ubus call $spobj reload
fi
}
mac80211_setup_adhoc_htmode( ) {
@ -579,12 +627,17 @@ mac80211_setup_adhoc_htmode() {
; ;
*) ibss_htmode = "" ; ;
esac
}
mac80211_setup_adhoc( ) {
local enable = $1
json_get_vars bssid ssid key mcast_rate
[ " $enable " = 0 ] && {
ip link set dev " $ifname " down
return 0
}
keyspec =
[ " $auth_type " = "wep" ] && {
set_default key 1
@ -623,8 +676,14 @@ mac80211_setup_adhoc() {
}
mac80211_setup_mesh( ) {
local enable = $1
json_get_vars ssid mesh_id mcast_rate
[ " $enable " = 0 ] && {
ip link set dev " $ifname " down
return 0
}
mcval =
[ -n " $mcast_rate " ] && wpa_supplicant_add_rate mcval " $mcast_rate "
[ -n " $mesh_id " ] && ssid = " $mesh_id "
@ -670,6 +729,7 @@ mac80211_setup_mesh() {
mac80211_setup_vif( ) {
local name = " $1 "
local failed
local action = up
json_select data
json_get_vars ifname
@ -678,13 +738,15 @@ mac80211_setup_vif() {
json_select config
json_get_vars mode
json_get_var vif_txpower txpower
json_get_var vif_enable enable 1
ip link set dev " $ifname " up || {
[ " $vif_enable " = 1 ] || action = down
logger ip link set dev " $ifname " $action
ip link set dev " $ifname " " $action " || {
wireless_setup_vif_failed IFUP_ERROR
json_select ..
return
}
set_default vif_txpower " $txpower "
[ -z " $vif_txpower " ] || iw dev " $ifname " set txpower fixed " ${ vif_txpower %%.* } 00 "
@ -693,9 +755,9 @@ mac80211_setup_vif() {
wireless_vif_parse_encryption
freq = " $( get_freq " $phy " " $channel " ) "
if [ " $wpa " -gt 0 -o " $auto_channel " -gt 0 ] || chan_is_dfs " $phy " " $channel " ; then
mac80211_setup_supplicant || failed = 1
mac80211_setup_supplicant $vif_enable || failed = 1
else
mac80211_setup_mesh
mac80211_setup_mesh $vif_enable
fi
for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING ; do
json_get_var mp_val " $var "
@ -707,13 +769,13 @@ mac80211_setup_vif() {
mac80211_setup_adhoc_htmode
if [ " $wpa " -gt 0 -o " $auto_channel " -gt 0 ] ; then
freq = " $( get_freq " $phy " " $channel " ) "
mac80211_setup_supplicant_noctl || failed = 1
mac80211_setup_supplicant_noctl $vif_enable || failed = 1
else
mac80211_setup_adhoc
mac80211_setup_adhoc $vif_enable
fi
; ;
sta)
mac80211_setup_supplicant || failed = 1
mac80211_setup_supplicant $vif_enable || failed = 1
; ;
esac
@ -734,18 +796,26 @@ chan_is_dfs() {
return $!
}
mac80211_interface_cleanup( ) {
local phy = " $1 "
mac80211_vap_cleanup( ) {
local service = " $1 "
local vaps = " $2 "
for wdev in $( list_phy_interfaces " $phy " ) ; do
local wdev_phy = " $( readlink /sys/class/net/${ wdev } /phy80211) "
wdev_phy = " $( basename " $wdev_phy " ) "
[ -n " $wdev_phy " -a " $wdev_phy " != " $phy " ] && continue
for wdev in $vaps ; do
ubus call ${ service } .${ phy } config_remove " {\"iface\":\" $wdev \"} "
ip link set dev " $wdev " down 2>/dev/null
iw dev " $wdev " del
done
}
mac80211_interface_cleanup( ) {
local phy = " $1 "
local primary_ap = $( uci -q -P /var/state get wireless._${ phy } .aplist)
primary_ap = ${ primary_ap %% * }
mac80211_vap_cleanup hostapd " ${ primary_ap } "
mac80211_vap_cleanup wpa_supplicant " $( uci -q -P /var/state get wireless._${ phy } .splist) "
}
mac80211_set_noscan( ) {
hostapd_noscan = 1
}
@ -771,8 +841,10 @@ drv_mac80211_setup() {
return 1
}
wireless_set_data phy = " $phy "
mac80211_interface_cleanup " $phy "
[ -z " $( uci -q -P /var/state show wireless._${ phy } ) " ] && {
uci -q -P /var/state set wireless._${ phy } = phy
wireless_set_data phy = " $phy "
}
# convert channel to frequency
[ " $auto_channel " -gt 0 ] || freq = " $( get_freq " $phy " " $channel " ) "
@ -822,30 +894,55 @@ drv_mac80211_setup() {
[ -n " $has_ap " ] && mac80211_hostapd_setup_base " $phy "
for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif
NEWAPLIST =
for_each_interface "ap" mac80211_prepare_vif
OLDAPLIST = $( uci -q -P /var/state get wireless._${ phy } .aplist)
NEW_MD5 = $( md5sum ${ hostapd_conf_file } )
OLD_MD5 = $( uci -q -P /var/state get wireless._${ phy } .md5)
if [ " ${ NEWAPLIST } " != " ${ OLDAPLIST } " ] ; then
mac80211_vap_cleanup hostapd " ${ OLDAPLIST } "
[ -n " ${ NEWAPLIST } " ] && mac80211_iw_interface_add " $phy " " ${ NEWAPLIST %% * } " __ap || return
fi
local add_ap = 0
local primary_ap = ${ NEWAPLIST %% * }
[ -n " $hostapd_ctrl " ] && {
/usr/sbin/hostapd -s -P /var/run/wifi-$phy .pid -B " $hostapd_conf_file "
if [ -n " $( ubus list | grep hostapd.$primary_ap ) " ] ; then
[ " ${ NEW_MD5 } " = " ${ OLD_MD5 } " ] || {
ubus call hostapd.$primary_ap reload
}
else
add_ap = 1
ubus call hostapd.${ phy } config_add " {\"iface\":\" $primary_ap \", \"config\":\" ${ hostapd_conf_file } \"} "
fi
ret = " $? "
wireless_add_process " $( cat /var/run/wifi-$phy .pid) " "/usr/sbin/hostapd" 1
[ " $ret " != 0 ] && {
wireless_setup_failed HOSTAPD_START_FAILED
return
}
}
uci -q -P /var/state set wireless._${ phy } .aplist= " ${ NEWAPLIST } "
uci -q -P /var/state set wireless._${ phy } .md5= " ${ NEW_MD5 } "
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
[ " ${ add_ap } " = 1 ] && sleep 1
for_each_interface "ap" mac80211_setup_vif
wireless_set_up
}
NEWSPLIST =
OLDSPLIST = $( uci -q -P /var/state get wireless._${ phy } .splist)
for_each_interface "sta adhoc mesh monitor" mac80211_setup_vif
list_phy_interfaces( ) {
local phy = " $1 "
if [ -d " /sys/class/ieee80211/ ${ phy } /device/net " ] ; then
ls " /sys/class/ieee80211/ ${ phy } /device/net " 2>/dev/null;
else
ls " /sys/class/ieee80211/ ${ phy } /device " 2>/dev/null | grep net: | sed -e 's,net:,,g'
fi
uci -q -P /var/state set wireless._${ phy } .splist= " ${ NEWSPLIST } "
local foundvap
local dropvap = ""
for oldvap in $OLDSPLIST ; do
foundvap = 0
for newvap in $NEWSPLIST ; do
[ " $oldvap " = " $newvap " ] && foundvap = 1
done
[ " $foundvap " = "0" ] && dropvap = " $dropvap $oldvap "
done
[ -n " $dropvap " ] && mac80211_vap_cleanup wpa_supplicant " $dropvap "
wireless_set_up
}
drv_mac80211_teardown( ) {
@ -856,6 +953,7 @@ drv_mac80211_teardown() {
json_select ..
mac80211_interface_cleanup " $phy "
uci -q -P /var/state revert wireless._${ phy }
}
add_driver mac80211