提交 ac20976d 编写于 作者: H Helmut Schaa 提交者: Johannes Berg

mac80211: Allow single vif mac address change with addr_mask

When changing the MAC address of a single vif mac80211 will check if
the new address fits into the address mask specified by the driver.
This only needs to be done when using multiple BSSIDs. Hence, check
the new address only against all other vifs.

Also fix the MAC address assignment on new interfaces if the user
changed the address of a vif such that perm_addr is not covered by
addr_mask anymore.

Resolves:
https://bugzilla.kernel.org/show_bug.cgi?id=57371Signed-off-by: NHelmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: NJakub Kicinski <kubakici@wp.pl>
Reported-by: NAlessandro Lannocca <alessandro.lannocca@gmail.com>
Cc: Alessandro Lannocca <alessandro.lannocca@gmail.com>
Cc: Bruno Randolf <br1@thinktube.com>
Signed-off-by: NJohannes Berg <johannes.berg@intel.com>
上级 c8aa22db
...@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) ...@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
return 0; 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)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_local *local = sdata->local;
struct ieee80211_sub_if_data *iter;
u64 new, mask, tmp; u64 new, mask, tmp;
u8 *m; u8 *m;
int ret = 0; int ret = 0;
...@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) ...@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) { list_for_each_entry(iter, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) if (iter == sdata)
continue; continue;
m = sdata->vif.addr; if (iter->vif.type == NL80211_IFTYPE_MONITOR)
continue;
m = iter->vif.addr;
tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
...@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) ...@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
if (ieee80211_sdata_running(sdata)) if (ieee80211_sdata_running(sdata))
return -EBUSY; return -EBUSY;
ret = ieee80211_verify_mac(sdata->local, sa->sa_data); ret = ieee80211_verify_mac(sdata, sa->sa_data);
if (ret) if (ret)
return ret; return ret;
...@@ -1486,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, ...@@ -1486,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
break; break;
} }
/*
* Pick address of existing interface in case user changed
* MAC address manually, default to perm_addr.
*/
m = local->hw.wiphy->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) | start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册