[OpenWrt-Devel] [PATCH 4/5] mac80211: add support for dynamically reconfiguring wifi
Daniel Golle
daniel at makrotopia.org
Wed Oct 30 11:58:19 EDT 2019
From: John Crispin <john at phrozen.org>
Change scripts to use ubus interface of hostapd/wpa_supplicant to
add/remove/modify wireless interfaces instead of (re-)starting the
services.
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
.../files/lib/netifd/wireless/mac80211.sh | 135 ++++++++++++++----
1 file changed, 107 insertions(+), 28 deletions(-)
diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
index f9d5c0c6d5..e62a53f5be 100644
--- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh
@@ -18,6 +18,11 @@ iw() {
command iw $@ || logger -t mac80211 "Failed command: iw $@"
}
+NEWAPLIST=
+OLDAPLIST=
+NEWSPLIST=
+OLDSPLIST=
+
drv_mac80211_init_device_config() {
hostapd_common_add_device_config
@@ -57,7 +62,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
@@ -456,7 +461,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))
@@ -492,8 +497,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}"
}
;;
@@ -505,7 +510,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"
@@ -531,19 +536,51 @@ mac80211_prepare_vif() {
}
mac80211_setup_supplicant() {
+ 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
+ [ -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 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 "
+
+ if [ -z "$spobj" ]; then
+ wpa_supplicant_run "$ifname"
+ else
+ ubus call $spobj reload
+ fi
}
mac80211_setup_adhoc_htmode() {
@@ -581,7 +618,6 @@ mac80211_setup_adhoc_htmode() {
;;
*) ibss_htmode="" ;;
esac
-
}
mac80211_setup_adhoc() {
@@ -672,6 +708,7 @@ mac80211_setup_mesh() {
mac80211_setup_vif() {
local name="$1"
local failed
+ local action=up
json_select data
json_get_vars ifname
@@ -680,13 +717,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"
@@ -736,15 +775,27 @@ 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
+ 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
}
@@ -770,8 +821,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")"
@@ -821,30 +874,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() {
@@ -855,6 +933,7 @@ drv_mac80211_teardown() {
json_select ..
mac80211_interface_cleanup "$phy"
+ uci -q -P /var/state revert wireless._${phy}
}
add_driver mac80211
--
2.23.0
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list