mac80211: track unmanaged interfaces
authorDaniel Golle <daniel@makrotopia.org>
Thu, 5 Dec 2019 17:22:55 +0000 (18:22 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Sun, 8 Dec 2019 18:52:39 +0000 (19:52 +0100)
In addition to wpa_supplicant and hostapd managed interfaces, also
track unmanaged interfaces. This is used to make sure that running
'wifi' always returns into a clean state regardless of what the user
did before.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh

index 91d50c35375478dc7fa749144bc8ae81c2ff3677..dd2b09c4a00d5fe16e1558aad516c73fcb229738 100644 (file)
@@ -19,6 +19,8 @@ NEWAPLIST=
 OLDAPLIST=
 NEWSPLIST=
 OLDSPLIST=
+NEWUMLIST=
+OLDUMLIST=
 
 drv_mac80211_init_device_config() {
        hostapd_common_add_device_config
@@ -666,6 +668,8 @@ mac80211_setup_adhoc() {
        local enable=$1
        json_get_vars bssid ssid key mcast_rate
 
+       NEWUMLIST="${NEWUMLIST}$ifname "
+
        [ "$enable" = 0 ] && {
                ip link set dev "$ifname" down
                return 0
@@ -712,6 +716,8 @@ mac80211_setup_mesh() {
        local enable=$1
        json_get_vars ssid mesh_id mcast_rate
 
+       NEWUMLIST="${NEWUMLIST}$ifname "
+
        [ "$enable" = 0 ] && {
                ip link set dev "$ifname" down
                return 0
@@ -800,7 +806,7 @@ mac80211_vap_cleanup() {
        local vaps="$2"
 
        for wdev in $vaps; do
-               ubus call ${service}.${phy} config_remove "{\"iface\":\"$wdev\"}"
+               [ "$service" != "none" ] && ubus call ${service}.${phy} config_remove "{\"iface\":\"$wdev\"}"
                ip link set dev "$wdev" down 2>/dev/null
                iw dev "$wdev" del
        done
@@ -813,6 +819,7 @@ mac80211_interface_cleanup() {
 
        mac80211_vap_cleanup hostapd "${primary_ap}"
        mac80211_vap_cleanup wpa_supplicant "$(uci -q -P /var/state get wireless._${phy}.splist)"
+       mac80211_vap_cleanup none "$(uci -q -P /var/state get wireless._${phy}.umlist)"
 }
 
 mac80211_set_noscan() {
@@ -845,6 +852,28 @@ drv_mac80211_setup() {
                wireless_set_data phy="$phy"
        }
 
+       OLDAPLIST=$(uci -q -P /var/state get wireless._${phy}.aplist)
+       OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist)
+       OLDUMLIST=$(uci -q -P /var/state get wireless._${phy}.umlist)
+
+       local wdev
+       local cwdev
+       local found
+
+       for wdev in $(list_phy_interfaces "$phy"); do
+               found=0
+               for cwdev in $OLDAPLIST $OLDSPLIST $OLDUMLIST; do
+                       if [ "$wdev" = "$cwdev" ]; then
+                               found=1
+                               break
+                       fi
+               done
+               if [ "$found" = "0" ]; then
+                       ip link set dev "$wdev" down
+                       iw dev "$wdev" del
+               fi
+       done
+
        # convert channel to frequency
        [ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")"
 
@@ -896,7 +925,6 @@ drv_mac80211_setup() {
        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
@@ -927,10 +955,12 @@ drv_mac80211_setup() {
        for_each_interface "ap" mac80211_setup_vif
 
        NEWSPLIST=
-       OLDSPLIST=$(uci -q -P /var/state get wireless._${phy}.splist)
+       NEWUMLIST=
+
        for_each_interface "sta adhoc mesh monitor" mac80211_setup_vif
 
        uci -q -P /var/state set wireless._${phy}.splist="${NEWSPLIST}"
+       uci -q -P /var/state set wireless._${phy}.umlist="${NEWUMLIST}"
 
        local foundvap
        local dropvap=""
@@ -945,6 +975,15 @@ drv_mac80211_setup() {
        wireless_set_up
 }
 
+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
+}
+
 drv_mac80211_teardown() {
        wireless_process_kill_all