]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/iface.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[karo-tx-linux.git] / net / mac80211 / iface.c
index 7cabaf261fede492c77f9aa93452000732c5cb15..a2a8250e2f845d6441f60e177357900d3d411155 100644 (file)
@@ -159,10 +159,11 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
+static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
                                bool check_dup)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_sub_if_data *iter;
        u64 new, mask, tmp;
        u8 *m;
        int ret = 0;
@@ -184,12 +185,15 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr,
                return ret;
 
        mutex_lock(&local->iflist_mtx);
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
-                   !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+       list_for_each_entry(iter, &local->interfaces, list) {
+               if (iter == sdata)
                        continue;
 
-               m = sdata->vif.addr;
+               if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
+                   !(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
+                       continue;
+
+               m = iter->vif.addr;
                tmp =   ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
@@ -218,7 +222,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
            !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
                check_dup = false;
 
-       ret = ieee80211_verify_mac(sdata->local, sa->sa_data, check_dup);
+       ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
        if (ret)
                return ret;
 
@@ -1503,7 +1507,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
                        break;
                }
 
+               /*
+                * Pick address of existing interface in case user changed
+                * MAC address manually, default to perm_addr.
+                */
                m = local->hw.wiphy->perm_addr;
+               list_for_each_entry(sdata, &local->interfaces, list) {
+                       if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
+                               continue;
+                       m = sdata->vif.addr;
+                       break;
+               }
                start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
                        ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
                        ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);