From 6311f639b39a6626f49af90de9ebf2023765eb3c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Tue, 27 Nov 2012 18:23:06 +0100 Subject: [PATCH] --- yaml --- r: 341973 b: refs/heads/master c: 478622e81c735ecd83d45ee6be3fd45d500aaa3b h: refs/heads/master i: 341971: e07878903e6521289fa33c496183c1a1d082cec6 v: v3 --- [refs] | 2 +- trunk/net/mac80211/iface.c | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 7859143aad9b..38be97ab7868 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0624760c96da3ffeaec8027a016475ae752d75e1 +refs/heads/master: 478622e81c735ecd83d45ee6be3fd45d500aaa3b diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index 5331662489f7..40c36d5d7377 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -223,6 +223,47 @@ 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) +{ + struct ieee80211_sub_if_data *sdata; + u64 new, mask, tmp; + u8 *m; + int ret = 0; + + if (is_zero_ether_addr(local->hw.wiphy->addr_mask)) + return 0; + + m = addr; + new = ((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); + + m = local->hw.wiphy->addr_mask; + mask = ((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); + + + mutex_lock(&local->iflist_mtx); + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR) + continue; + + m = sdata->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); + + if ((new & ~mask) != (tmp & ~mask)) { + ret = -EINVAL; + break; + } + } + mutex_unlock(&local->iflist_mtx); + + return ret; +} + static int ieee80211_change_mac(struct net_device *dev, void *addr) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -232,6 +273,10 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) if (ieee80211_sdata_running(sdata)) return -EBUSY; + ret = ieee80211_verify_mac(sdata->local, sa->sa_data); + if (ret) + return ret; + ret = eth_mac_addr(dev, sa); if (ret == 0)